精华内容
下载资源
问答
  • vue-router实现原理

    2020-03-11 17:45:57
    近期面试,遇到关于vue-router实现原理的问题,在查阅了相关资料后,根据自己理解,来记录下。 我们知道vue-routervue的核心插件,而当前vue项目一般都是单页面应用,也就是说vue-router是应用在单页面应用中的。 ...

    近期面试,遇到关于vue-router实现原理的问题,在查阅了相关资料后,根据自己理解,来记录下。
    我们知道vue-router是vue的核心插件,而当前vue项目一般都是单页面应用,也就是说vue-router是应用在单页面应用中的。
    那么,什么是单页面应用呢?在单页面应用出现之前,多页面应用又是什么样子呢?

    单页面应用与多页面应用

    单页面

    即 第一次进入页面的时候会请求一个html文件,刷新清除一下。切换到其他组件,此时路径也相应变化,但是并没有新的html文件请求,页面内容也变化了。

    原理是:JS会感知到url的变化,通过这一点,可以用js动态的将当前页面的内容清除掉,然后将下一个页面的内容挂载到当前页面上,这个时候的路由不是后端来做了,而是前端来做,判断页面到底是显示哪个组件,清除不需要的,显示需要的组件。这种过程就是单页应用,每次跳转的时候不需要再请求html文件了。

    多页面

    即 每一次页面跳转的时候,后台服务器都会给返回一个新的html文档,这种类型的网站也就是多页网站,也叫做多页应用。
    原理是:传统的页面应用,是用一些超链接来实现页面切换和跳转的

    其实刚才单页面应用跳转原理即 vue-router实现原理

    vue-router实现原理

    原理核心就是 更新视图但不重新请求页面。

    vue-router实现单页面路由跳转,提供了三种方式:hash模式、history模式、abstract模式,根据mode参数来决定采用哪一种方式。

    路由模式

    vue-router 提供了三种运行模式:
    ● hash: 使用 URL hash 值来作路由。默认模式。
    ● history: 依赖 HTML5 History API 和服务器配置。查看 HTML5 History 模式。
    ● abstract: 支持所有 JavaScript 运行环境,如 Node.js 服务器端

    Hash模式

    hash即浏览器url中#后面的内容,包含#。hash是URL中的锚点,代表的是网页中的一个位置,单单改变#后的部分,浏览器只会加载相应位置的内容,不会重新加载页面。
    也就是说

    即#是用来指导浏览器动作的,对服务器端完全无用,HTTP请求中,不包含#。
    每一次改变#后的部分,都会在浏览器的访问历史中增加一个记录,使用”后退”按钮,就可以回到上一个位置。
    所以说Hash模式通过锚点值的改变,根据不同的值,渲染指定DOM位置的不同数据。

    History模式

    HTML5 History API提供了一种功能,能让开发人员在不刷新整个页面的情况下修改站点的URL,就是利用 history.pushState API 来完成 URL 跳转而无须重新加载页面;

    由于hash模式会在url中自带#,如果不想要很丑的 hash,我们可以用路由的 history 模式,只需要在配置路由规则时,加入"mode: ‘history’",这种模式充分利用 history.pushState API 来完成 URL 跳转而无须重新加载页面。

    有时,history模式下也会出问题:
    eg:
    hash模式下:xxx.com/#/id=5 请求地址为 xxx.com,没有问题。
    history模式下:xxx.com/id=5 请求地址为 xxx.com/id=5,如果后端没有对应的路由处理,就会返回404错误;

    为了应对这种情况,需要后台配置支持:
    在服务端增加一个覆盖所有情况的候选资源:如果 URL 匹配不到任何静态资源,则应该返回同一个 index.html 页面,这个页面就是你 app 依赖的页面。

    abstract模式

    abstract模式是使用一个不依赖于浏览器的浏览历史虚拟管理后端。
    根据平台差异可以看出,在 Weex 环境中只支持使用 abstract 模式。 不过,vue-router 自身会对环境做校验,如果发现没有浏览器的 API,vue-router 会自动强制进入 abstract 模式,所以 在使用 vue-router 时只要不写 mode 配置即可,默认会在浏览器环境中使用 hash 模式,在移动端原生环境中使用 abstract 模式。 (当然,你也可以明确指定在所有情况下都使用 abstract 模式)。

    展开全文
  • 主要介绍了vue-router实现原理及两种模式分析,给大家介绍了vue-router hash模式与history模式不同模式下处理逻辑,需要的朋友可以参考下
  • Vue-router实现原理

    2020-11-13 21:14:30
    vue-router实现原理 路由有两种模式,分别是hash模式/history模式 hash模式 1、URL中#后面的内容作为路径地址 2、监听hashchange时间 3、根据当前路由路径地址找到对应组件重新渲染 history模式 1、通过histo....

    在这里插入图片描述

    vue-router实现原理
    路由有两种模式,分别是hash模式/history模式
    
    hash模式
    
    1、URL中#后面的内容作为路径地址
    
    2、监听hashchange时间
    
    3、根据当前路由路径地址找到对应组件重新渲染
    
    history模式
    
    1、通过histo.pushState()方法改变地址栏
    
    2、监听popstate事件
    
    3、根据当前路由地址找到对应组件重新渲染
    
    vue-router核心代码
    // vue-router路由配置文件
    import Vue from 'vue' //引入vue
    import VueRouter from 'vue-router' //引入路由
    import Index from '../views/Index.vue' //引入页面组件
    
    Vue.use(VueRouter)
    
    const routes = [
      {
        path: '/',
        name: 'Index',
        component: Index
      },
      {
        path: '/detail/:id',
        name: 'Detail',
        props: true,
        component: () => import(/* webpackChunkName: "detail" */ '../views/Detail.vue')
      }
    ]
    
    const router = new VueRouter({
      routes
    })
    
    export default router //导出路由配置
    
    //main.js配置文件
    从上面的new VueRouter来看 Vue-router其实是一个构造函数,里面有不同的函数
    
    vue挂载vue-router
    import Vue from 'vue'
    
    import App from './App.vue'
    
    import router from './router'
    
    new Vue({
      router,
      render: h => h(App)
    }).$mount('#app')
    
    
    vue-router构造函数
    vue-router构造函数内容如下
    
    class类名: VueRouter
    
    属性: 总共有3个
    
    options 记录构造函数中传入的对象,用来记录路由规则
    
    data 是一个对象里面有一个属性current,current用来记录当前路由地址的,此处设置data对象的目的是,
    需要一个响应式的对象,也就是data对象是响应式的对象,当路由发生变化后对应的组件要自动更新,
    
    routeMap是一个对象,记录路由地址和组件的对应关系,后续把路由规则解析到routeMap里面
    
    vue-router里面的方法
    //+这个方法对外暴露
    //_属于静态方法
    +Constructor(Options):VueRouter//初始属性
    
    _install(Vue):void //静态方法 用来实现vue的插件机制
    
    +init():void//用来调用下面的3个方法
    
    +initEvent():void //监听浏览器历史的变化
    
    +createRouteMap():void//初始化 routeMap属性,把构造函数传入的路由规则,以键值对的形式存在,
    //存储在routeMap里面,键就是对应的地址 ,值就是对应的组件,会在route-view组件中使用route-map
    
    +initComponents(Vue):void//创建route-link和route-view组件的
    

    本篇文章涉及原理的实现,如果想看原理的实现,请看接下来的文章
    谢谢观看,如有不足,敬请指教

    展开全文
  • 路由就是用来跟后端服务器进行交互的一种方式,通过不同的路径,来请求不同的资源,请求不同的页面是路由的其中一种功能。这篇文章主要介绍了前端路由简介以及vue-router实现原理,需要的朋友可以参考下
  • vue-Router实现原理

    千次阅读 2020-10-27 10:40:51
    一、前端路由概念 通过改变 URL,在不重新请求页面的情况下,更新页面视图。 二、vue-Router两种模式 更新视图但不重新请求页面,是前端路由...const router=new VueRouter({ mode:'history', routes:[...] }) m

    一、前端路由概念

    通过改变 URL,在不重新请求页面的情况下,更新页面视图。

    二、vue-Router两种模式

    更新视图但不重新请求页面,是前端路由原理的核心之一,目前在浏览器环境中这一功能的实现主要有2种方式:

    1. Hash — 默认值,利用 URL 中的hash("#") 、

    2. history-- 利用URL中的路径(/home)

    如何设置路由模式

    const router=new VueRouter({
        mode:'history',
        routes:[...]
    })
    

    mode 区别:

    1. mode:“hash” 多了 “#”
    http://localhost:8080/#/login
    
    1. mode:“history”
    http://localhost:8080/home
    

    三、HashHistory

    hash("#")的作用是加载 URL 中指示网页中的位置。# 号后面的 hash值,可通过 window.location.hash 获取

    特点:

    1. hash 不会被包括在 http 请求中,,对服务器端完全无用,因此,改变 hash 不会重新加载页面。

    2. 可以为 hash 的改变添加监听事件:window.addEventListener("hashchange",funcRef,false)

    3. 每一次改变 hash(window.localtion.hash),都会在浏览器访问历史中增加一个记录。

    利用 hash 的以上特点,就可以来实现前端路由"更新视图但不重新请求页面"的功能了。

    HashHistory 拥有两个方法,一个是 push, 一个是 replace

    两个方法:HashHistory.push() 和 HashHistory.replace()
    

    HashHistory.push() 将新路由添加到浏览器访问历史的栈顶

    在这里插入图片描述
    从设置路由改变到视图更新的流程:

    $router.push() --> HashHistory.push() -->History.transitionTo() --> History.updateRoute() --> {app._route = route} --> vm.render()

    解释:

    $router.push() //调用方法
    HashHistory.push()//根据hash模式调用,设置hash并添加到浏览器历史记录(添加到栈顶)(window.location.hash= XXX)
    History.transitionTo() //监测更新,更新则调用History.updateRoute()
    History.updateRoute() //更新路由
    {app._route= route} //替换当前app路由
    vm.render() //更新视图

    HashHistory.replace()

    replace()方法与push()方法不同之处在于,它并不是将新路由添加到浏览器访问历史的栈顶,而是替换掉当前的路由

    在这里插入图片描述

    四、HTML5History

    早期History通过back()、forward()、go()等方法,我们可以读取浏览器历史记录栈的信息
    从HTML5开始History提供了2个新的方法:pushState()、replaceState()
    使得我们可以对浏览器历史记录栈进行修改:

    window.history.pushState(data, title, targetURL);
    @状态对象:传给目标路由的信息,可为空
    @页面标题:目前所有浏览器都不支持,填空字符串即可
    @可选url:目标url,不会检查url是否存在,且不能跨域。如不传该项,即给当前url添加data
    
    window.history.replaceState(data, title, targetURL);
    @类似于pushState,但是会直接替换掉当前url,而不会在history中留下记录
    

    假定当前网址是example.com/1.html,使用pushState()方法在浏览记录(History 对象)中添加一个新记录。

    var stateObj = { foo: 'bar' };
    history.pushState(stateObj, 'page 2', '2.html');
    

    添加新记录后,浏览器地址栏立刻显示example.com/2.html,但并不会跳转到2.html,甚至也不会检查2.html是否存在,它只是成为浏览历史中的最新记录。

    这2个方法有个共同的特点:当调用他们修改浏览器历史栈后,虽然当前url改变了,但浏览器不会立即发送请求该url,这就为单页应用前端路由,更新视图但不重新请求页面提供了基础

    更多操作:

    history.pushState({page: 1}, 'title 1', '?page=1')
    // URL 显示为 http://example.com/example.html?page=1
    
    history.pushState({page: 2}, 'title 2', '?page=2');
    // URL 显示为 http://example.com/example.html?page=2
    
    history.replaceState({page: 3}, 'title 3', '?page=3');
    // URL 显示为 http://example.com/example.html?page=3
    
    history.back()
    // URL 显示为 http://example.com/example.html?page=1
    
    history.back()
    // URL 显示为 http://example.com/example.html
    
    history.go(2)
    // URL 显示为 http://example.com/example.html?page=3
    
    

    监听地址变化

    在HTML5History的构造函数中监听popState(window.onpopstate)

    popstate事件会在点击后退、前进按钮(或调用history.back()、history.forward()、history.go()方法)时触发。前提是不能真的发生了页面跳转,而是在由history.pushState()或者history.replaceState()形成的历史节点中前进后退
    注意:用history.pushState()或者history.replaceState()不会触发popstate事件。

    window.onpopstate = function(event) {
      console.log(event.state);
      console.log(window.history.state;);
    };
    

    以上两种方式皆可获取之前在pushStatereplaceState中传入的data

    注意,页面第一次加载的时候,浏览器不会触发popstate事件。

    五、两种模式比较

    1. pushState设置的新URL可以是与当前URL同源的任意URL;而hash只可修改#后面的部分,故只可设置与当前同文档的URL

    2. pushState通过stateObject可以添加任意类型的数据到记录中;而hash只可添加短字符串

    3. pushState可额外设置title属性供后续使用

    4. history模式则会将URL修改得就和正常请求后端的URL一样,如后端没有配置对应/user/id的路由处理,则会返回404错误

    辅助学习代码:

    <!DOCTYPE html>
    <html lang="en">
    
    <head>
        <meta charset="UTF-8">
        <title>pushState</title>
        <style type="text/css">
        .hidden {
            display: none;
        }
        </style>
    <script src="http://libs.baidu.com/jquery/2.0.0/jquery.min.js"></script>
    </head>
    
    <body>
        <section id="step1" class="step-contain" step="1">
            <p>1</p>
            <button class="step-btn" step="1">下一步</button>
        </section>
        <section id="step2" class="step-contain hidden" step="2">
            <p>2</p>
            <button class="step-btn" step="2">下一步</button>
        </section>
        <section id="step3" class="step-contain hidden" step="3">
            <p>3</p>
        </section>
        <script type="text/javascript">
        $(function() {
            stepProgress();
    
            function stepProgress() {
                var options = {
                    curStep: 1,
                    nextStep: null
                }
                var defaultState={
                    "step": options.curStep,
                     "url": "#step=" + options.curStep
                }
                window.history.pushState(defaultState, "", defaultState.url);
                $(".step-btn").on("click", function() {
                    var step = parseInt($(this).attr("step"));
                    options.nextStep = step + 1;
                    var state = {
                        "step": options.nextStep,
                        "url": "#step=" + options.nextStep
                    }
                    window.history.pushState(state, "", state.url);
                    console.log(state.step)
                    swapStaus(options.nextStep);
                });
    
                function swapStaus(step) {
                    $(".step-contain").each(function() {
                        var tmpStep = $(this).attr("step");
                        if (parseInt(tmpStep) == step) {
                            $("#step" + tmpStep).removeClass("hidden");
                        } else {
                            $("#step" + tmpStep).addClass("hidden");
                        }
                    });
                    options.curStep = step;
                }
    
                $(window).on("popstate",function(){
                    var currentState = history.state;
                    goStep=currentState.step?currentState.step:1;
                    swapStaus(goStep)
                })
            }
    
        })
        </script>
    </body>
    
    </html>
    
    展开全文
  • vue-router实现原理浅析

    2020-05-14 21:12:54
    vue-router实现原理 SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是:更新视图而不重新请求...

    vue-router 使用详情

    vue-router实现原理

    SPA(single page application):单一页面应用程序,只有一个完整的页面;它在加载页面时,不会加载整个页面,而是只更新某个指定的容器中内容。单页面应用(SPA)的核心之一是:更新视图而不重新请求页面;vue-router在实现单页面前端路由时,提供了两种方式:Hash模式和History模式。

    1、hash模式

    随着 ajax 的流行,异步数据请求交互运行在不刷新浏览器的情况下进行。而异步交互体验的更高级版本就是 SPA —— 单页应用。单页应用不仅仅是在页面交互是无刷新的,连页面跳转都是无刷新的,为了实现单页应用,所以就有了前端路由。类似于服务端路由,前端路由实现起来其实也很简单,就是匹配不同的 url 路径,进行解析,然后动态的渲染出区域 html 内容。但是这样存在一个问题,就是 url 每次变化的时候,都会造成页面的刷新。那解决问题的思路便是在改变url的情况下,保证页面的不刷新。在 2014 年之前,大家是通过 hash 来实现路由,url hash 就是类似于:

    http://www.xxx.com/#/login
    

    这种 #。后面 hash 值的变化,并不会导致浏览器向服务器发出请求,浏览器不发出请求,也就不会刷新页面。另外每次 hash 值的变化,还会触发hashchange 这个事件,通过这个事件我们就可以知道 hash 值发生了哪些变化。然后我们便可以监听hashchange来实现更新页面部分内容的操作:

    function matchAndUpdate () {
       // todo 匹配 hash 做 dom 更新操作
    }
    
    window.addEventListener('hashchange', matchAndUpdate)
    

    2、history 模式

    14年后,因为HTML5标准发布。多了两个 API,pushState 和 replaceState,通过这两个 API 可以改变 url 地址且不会发送请求。同时还有popstate事件。通过这些就能用另一种方式来实现前端路由了,但原理都是跟 hash 实现相同的。用了HTML5的实现,单页路由的url就不会多出一个#,变得更加美观。但因为没有 # 号,所以当用户刷新页面之类的操作时,浏览器还是会给服务器发送请求。为了避免出现这种情况,所以这个实现需要服务器的支持,需要把所有路由都重定向到根页面。

    function matchAndUpdate () {
       // todo 匹配路径 做 dom 更新操作
    }
    
    window.addEventListener('popstate', matchAndUpdate)
    

    vue-router的使用

    1、动态路由匹配

    我们经常需要把某种模式匹配到的所有路由,全都映射到同个组件。例如,我们有一个 User 组件,对于所有 ID 各不相同的用户,都要使用这个组件来渲染。那么,我们可以在 vue-router 的路由路径中使用“动态路径参数”(dynamic segment) 来达到这个效果

    const User = {
      template: '<div>User</div>'
    }
    
    const router = new VueRouter({
      routes: [
        // 动态路径参数 以冒号开头
        { path: '/user/:id', component: User }
      ]
    })
    

    现在呢,像 /user/foo 和 /user/bar 都将映射到相同的路由。

    一个“路径参数”使用冒号 : 标记。当匹配到一个路由时,参数值会被设置到 this.$route.params,可以在每个组件内使用。于是,我们可以更新 User 的模板,输出当前用户的 ID:

    const User = {
      template: '<div>User {{ $route.params.id }}</div>'
    }
    

    你可以在一个路由中设置多段『路径参数』,对应的值都会设置到 $route.params 中。例如:

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-9H46Y6nf-1589461925149)(/Users/mxj/Library/Application Support/typora-user-images/image-20200106095618907.png)]

    提醒一下,当使用路由参数时,例如从/user/foo导航到/user/bar,原来的组件实例会被复用。因为两个路由都渲染同个组件,比起销毁再创建,复用则显得更加高效。不过,这也意味着组件的生命周期钩子不会再被调用。复用组件时,想对路由参数的变化作出响应的话,你可以简单地 watch (监测变化) $route 对象

    const User = {
      template: '...',
      watch: {
        '$route' (to, from) {
          // 对路由变化作出响应...
        }
      }
    }
    

    或者使用 2.2 中引入的 beforeRouteUpdate 守卫:

    const User = {
      template: '...',
      beforeRouteUpdate (to, from, next) {
        // react to route changes...
        // don't forget to call next()
      }
    }
    

    2、嵌套路由

    实际生活中的应用界面,通常由多层嵌套的组件组合而成。同样地,URL 中各段动态路径也按某种结构对应嵌套的各层组件,例如

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-FJtV4G3h-1589461925152)(/Users/mxj/Library/Application Support/typora-user-images/image-20200106095715387.png)]

    借助 vue-router,使用嵌套路由配置,就可以很简单地表达这种关系

    <div id="app">
      <router-view></router-view>
    </div>
    
    const User = {
      template: '<div>User {{ $route.params.id }}</div>'
    }
    
    const router = new VueRouter({
      routes: [
        { path: '/user/:id', component: User }
      ]
    })
    

    这里的是最顶层的出口,渲染最高级路由匹配到的组件。同样地,一个被渲染组件同样可以包含自己的嵌套。例如,在 User 组件的模板添加一个 router-view

    const User = {
      template: `
        <div class="user">
          <h2>User {{ $route.params.id }}</h2>
          <router-view></router-view>
        </div>
      `
    }
    

    要在嵌套的出口中渲染组件,需要在 VueRouter 的参数中使用 children 配置:

    const router = new VueRouter({
      routes: [
        { path: '/user/:id', component: User,
          children: [
            {
              // 当 /user/:id/profile 匹配成功,
              // UserProfile 会被渲染在 User 的 <router-view> 中
              path: 'profile',
              component: UserProfile
            },
            {
              // 当 /user/:id/posts 匹配成功
              // UserPosts 会被渲染在 User 的 <router-view> 中
              path: 'posts',
              component: UserPosts
            }
          ]
        }
      ]
    })
    

    3、编程式导航

    注意:在 Vue 实例内部,你可以通过 $router访问路由实例。因此你可以调用 this.$router.push

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-1ATHwa1u-1589461925153)(/Users/mxj/Library/Application Support/typora-user-images/image-20200106095826163.png)]

    ```参数可以是一个字符串路径,或者一个描述地址的对象:// 字符串router.push('home')// 对象router.push({ path: 'home' })// 命名的路由router.push({ name: 'user', params: { userId: 123 }})// 带查询参数,变成 /register?plan=privaterouter.push({ path: 'register', query: { plan: 'private' }})const userId = '123'router.push({ name: 'user', params: { userId }}) // -> /user/123router.push({ path: /user/${userId} }) // -> /user/123// 这里的 params 不生效router.push({ path: '/user', params: { userId }}) // -> /user//router.go(n)这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)// 在浏览器记录中前进一步,等同于 history.forward()router.go(1)// 后退一步记录,等同于 history.back()router.go(-1)// 前进 3 步记录router.go(3)// 如果 history 记录不够用,那就默默地失败呗router.go(-100)router.go(100)go
    参数可以是一个字符串路径,或者一个描述地址的对象:

    // 字符串
    router.push(‘home’)

    // 对象
    router.push({ path: ‘home’ })

    // 命名的路由
    router.push({ name: ‘user’, params: { userId: 123 }})

    // 带查询参数,变成 /register?plan=private
    router.push({ path: ‘register’, query: { plan: ‘private’ }})

    const userId = ‘123’
    router.push({ name: ‘user’, params: { userId }}) // -> /user/123
    router.push({ path: /user/${userId} }) // -> /user/123
    // 这里的 params 不生效
    router.push({ path: ‘/user’, params: { userId }}) // -> /user

    //router.go(n)这个方法的参数是一个整数,意思是在 history 记录中向前或者后退多少步,类似 window.history.go(n)
    // 在浏览器记录中前进一步,等同于 history.forward()
    router.go(1)

    // 后退一步记录,等同于 history.back()
    router.go(-1)

    // 前进 3 步记录
    router.go(3)

    // 如果 history 记录不够用,那就默默地失败呗
    router.go(-100)
    router.go(100)

    
    ## 4、命名视图
    
    有时候想同时 (同级) 展示多个视图,而不是嵌套展示,例如创建一个布局,有 sidebar (侧导航) 和 main (主内容) 两个视图,这个时候命名视图就派上用场了。你可以在界面中拥有多个单独命名的视图,而不是只有一个单独的出口。如果 router-view 没有设置名字,那么默认为 default。
    
    ​```jsx
    //name对应的是组件名字
    <router-view class="view one"></router-view>
    <router-view class="view two" name="a"></router-view>
    <router-view class="view three" name="b"></router-view>
    

    一个视图使用一个组件渲染,因此对于同个路由,多个视图就需要多个组件。确保正确使用 components 配置 (带上 s):

    const router = new VueRouter({
      routes: [
        {
          path: '/',
          components: {
            default: Foo,//Foo是组件名字
            a: Bar,//Bar是组件名字
            b: Baz//Baz是组件名字
          }
        }
      ]
    })
    

    嵌套命名视图

    UserSettings 组件的`部分应该是类似下面的这段代码:

    <!-- UserSettings.vue -->
    <div>
      <h1>User Settings</h1>
      <NavBar/>
      <router-view/>
      <router-view name="helper"/>
    </div>
    

    然后你可以用这个路由配置完成该布局:

    {
      path: '/settings',
      // 你也可以在顶级路由就配置命名视图
      component: UserSettings,
      children: [{
        path: 'emails',
        component: UserEmailsSubscriptions
      }, {
        path: 'profile',
        components: {
          default: UserProfile,
          helper: UserProfilePreview
        }
      }]
    }
    

    5、重定向与别名

    重定向也是通过 routes 配置来完成,下面例子是从 /a 重定向到 /b:

    const router = new VueRouter({
      routes: [
        { path: '/a', redirect: '/b' }
      ]
    })
    

    重定向的目标也可以是一个命名的路由:

    const router = new VueRouter({
      routes: [
        { path: '/a', redirect: { name: 'foo' }}
      ]
    })
    

    甚至是一个方法,动态返回重定向目标:

    const router = new VueRouter({
      routes: [
        { path: '/a', redirect: to => {
          // 方法接收 目标路由 作为参数
          // return 重定向的 字符串路径/路径对象
        }}
      ]
    })
    

    别名:/a 的别名是 /b,意味着,当用户访问 /b 时,URL 会保持为 /b,但是路由匹配则为 /a,就像用户访问 /a 一样。

    const router = new VueRouter({
      routes: [
        { path: '/a', component: A, alias: '/b' }
      ]
    })
    

    总结:

    • 『重定向』的意思是:当用户访问/a时,URL将会被替换成/b,然后匹配路由为/b。(换药换汤)
    • 别名的意思是:/a的别名是/b,意味着,当用户访问/b时,URL会保持为/b,但是路由匹配则为/a,就像用户访问/a 一样。(换汤不换药)

    传参及获取参数

    const User = {
      template: `
        <div class="user">
          <h2>User {{ $route.params.id }}</h2>
          <router-view></router-view>
        </div>
      `
    }
    

    $route.params 为域名#后的参数,如name localhost/name/王画画

    $route.query 为问号后的参数,如id localhost/name/王画画?age=10

    嵌套路由

    由children属性实现,比如了解跟多more页面。

    <!-- UserSettings.vue -->
    <div>
      <h1>我叫:{{ $router.params.name}}</h1>
      <router-link to = 'more' append>更多信息</router-link>
      //或者
      <router-link :to ="'user' + $router.param.name + '/more'" append>更多信息</router-link>
      <router-view/>
    </div>
    
    {
      path: '/about/:name',
      // 你也可以在顶级路由就配置命名视图
      component: About,
      children: [{
        path: '/more',
        component: More
      }]
    }
    

    手动访问和传参

    <button @click="surf">漫游</button>
    
    new Vue({
    	...
    	methods: {
    		surf: function(){
    			setTimeout(function(){
    				this.router.push('/about')
    				//或者
    				this.router.push(name)
    			})
    		}
    	}
    	...
    })
    

    导航钩子/守卫

    导航守卫即导航的生命周期,

    beforEach: 路由跳转之前的函数,如登录验证

    afterEach:

    元数据及路由匹配

    用在嵌套路由中,

    在父路由中增加 meta 设置

    展开全文
  • vue-router 实现原理 查看vue-router源码 github链接 vue-router 实例化时会初始化 this.history,不同 mode 对应不同的 history constructor (options: RouterOptions = {}) { this.mode = mode switch (mode) ...
  • (1)vue-router实现原理 vue-router提供三种路由模式 1.hash模式 默认模式,通过路径中的hash值来控制路由跳转,不存在兼容问题 hash模式实现原理 在正常路径后跟一个 # 号,匹配 # 后边的路径为前端路由,通过window...
  • vue-router实现原理 vue-router提供三种路由模式 1.hash模式 默认模式,通过路径中的hash值来控制路由跳转,不存在兼容问题 hash模式实现原理 在正常路径后跟一个 # 号,匹配 # 后边的路径为前端路由,通过window....
  • vue-router实现原理分享

    2020-11-03 19:13:04
    vue-router 是什么 首先我们需要知道vue-router是什么,它是干什么的? 这里的路由并不是指我们平时所说的硬件路由器,这里的路由就是SPA(单页应用)的路径管理器。 换句话说,vue-router就是WebApp的链接路径管理...
  • 1: Vue-Router 基本回顾 1-1: Vue-Router 基本使用 动态路由 嵌套路由 命名路由(给路由取名子) 以及 编程式导航 ...import VueRouter from 'vue-router' import Index from '../views/Index.vue' 1: 注册路由...
  • 这里提供了一个 install 方法,使用 Vue.mixin 混入 beforeCreate 和 destroyed 钩子函数,并全局注册 router-view 和 router-link 组件。 import View from './components/view' import Link from './com

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 14,322
精华内容 5,728
关键字:

vue-router的实现原理

vue 订阅