美文网首页
VueRouter 对象

VueRouter 对象

作者: _1633_ | 来源:发表于2020-12-16 23:36 被阅读0次

VueRouter 的实现是⼀个类,首先看看 constructor 构造函数。

    其中 this.app 表示根 Vue 实例, this.apps 保存所有⼦组件的Vue 实例, this.options 保存传⼊的路由配置, this.beforeHooks 、this.resolveHooks 、 this.afterHooks 表示⼀些钩子函数, this.matcher表⽰路由匹配器, this.fallback 表⽰路由创建失败的回调函数, this.mode表示路由创建的模式, this.history 表⽰路由历史的具体的实现实例,它是根据 this.mode 的不同实现不同,它有 History 基类,然后不同的 history 实现都是继承 History 。

当我们 new Vue{ router : new VueRouter({

  routes: []

   })

})

候会把 router 作为配置的属性传⼊,当我们在 beforeCreated 混入的时候

所以每个组件在执⾏ beforeCreated 钩⼦函数的时候,都会执⾏ router.init ⽅法

    init 的逻辑很简单,它传⼊的参数是 Vue 实例,然后存储到 this.apps 中;只有根 Vue 实例会保存到 this.app 中,并且会拿到当前的 this.history ,根据它的不同类型来执⾏不同逻辑,由于我们平时使⽤ hash 路由多⼀些,所以我们先看这部分逻辑,先定义了 setupHashListener函数,接着执⾏了 history.transitionTo ⽅法。

matcher

    在  VueRouter 的 constructor 中  this.matcher = createMatcher(options.routes || [], this)。

    matcher 相关的实现都在 src/create-matcher.js 中,

    createMatcher 接受两个参数, ⼀个是 router ,它是我们 new VueRouter 返回的实例,⼀个是routes ,它是⽤户定义的路由配置,createMatcher 返回了 match 和 addRoutes 两个方法

    createRouteMap 函数的⽬标是把⽤户的路由配置转换成⼀张路由映射表,它包含 3 个部分, pathList 存储所有的 path , pathMap 表⽰⼀个 path 到 RouteRecord 的映射关系,⽽nameMap 表示 name 到 RouteRecord 的映射关系。

    看下 RouteRecord 的 定义

RouteRecord

    RouteRecord 的创建是通过遍历 routes 为每⼀个 route 执⾏ addRouteRecord ⽅法⽣成⼀条记录。

     RouteRecord 中 path 是规范化后的路径,它会根据 parent 的 path 做计算; regex 是⼀个正则表达式的扩展,它利⽤了 path-to-regexp 这个⼯具库,把 path 解析成⼀个正则表达式的扩展;components 是⼀个对象,通常我们在配置中写的 component 实际上这⾥会被转换成{components: route.component} ; instances 表⽰组件的实例,也是⼀个对象类型; parent

表示父的 RouteRecord ,因为我们配置的时候有时候会配置⼦路由,所以整个 RouteRecord 也就是⼀个树型结构。

    如果配置了 children ,那么递归执⾏ addRouteRecord ⽅法,并把当前的 record 作为parent 传入,通过这样的深度遍历,我们就可以拿到⼀个 route 下的完整记录。

    然后就是 给 pathMap,pathList, 或者 nameMap 添加记录

由于 pathList 、 pathMap 、 nameMap 都是引⽤类型,所以在遍历整个 routes 过程中去执⾏addRouteRecord ⽅法,会不断给他们添加数据。那么经过整个 createRouteMap ⽅法的执⾏,我们得到的就是 pathList 、 pathMap 和 nameMap 。其中 pathList 是为了记录路由配置中的所有path ,而 pathMap 和 nameMap 都是为了通过 path 和 name 能快速查到对应的RouteRecord 。

addRoutes

    addRoutes ⽅法的作⽤是动态添加路由配置,在实际开发中有些场景是需要根据⼀些条件动态添加路由,所以 Vue-Router 也提供了这⼀接⼝

addRoutes 的⽅法⼗分简单,再次调⽤ createRouteMap 即可,传⼊新的 routes 配置,由于pathList 、 pathMap 、 nameMap 都是引⽤类型,执⾏ addRoutes 后会修改它们的值。

回到 createMatcher 的 match 方法

match ⽅法接收 3 个参数,其中 raw 是 RawLocation 类型,它可以是⼀个 url 字符串,也可以是⼀个 Location 对象; currentRoute 是 Route 类型,它表⽰当前的路径; redirectedFrom 和重定向相关,这⾥先忽略。 match ⽅法返回的是⼀个路径,它的作⽤是根据传⼊的 raw 和当前的路径 currentRoute 计算出⼀个新的路径并返回。

Location 和 Route 类型

normalizeLocation ⽅法的作⽤是根据 raw , current 计算出新的 location 。计算出新的 location 后,对 location 的 name 和 path 的两种情况做了处理。

name: 有 name 的情况下就根据 nameMap 匹配到 record ,它就是⼀个 RouterRecord 对象,如果record 不存在,则匹配失败,返回⼀个空路径;然后拿到 record 对应的 paramNames ,再对⽐currentRoute 中的 params ,把交集部分的 params 添加到 location 中,然后在通过fillParams ⽅法根据 record.path 和 location.path 计算出 location.path ,最后调⽤_createRoute(record, location, redirectedFrom) 去⽣成⼀条新路径,该⽅法我们之后会介绍。

path:通过 name 我们可以很快的找到 record ,但是通过 path 并不能,因为我们计算后的location.path 是⼀个真实路径,⽽ record 中的 path 可能会有 param ,因此需要对所有的pathList 做顺序遍历, 然后通过 matchRoute 方法根据record.regex 、 location.path 、 location.params 匹配,如果匹配到则也通过_createRoute(record, location, redirectedFrom) 去⽣成⼀条新路径。因为是顺序遍历,所以我们书写路由配置要注意路径的顺序,因为写在前⾯的会优先尝试匹配。

    然后调用 _createRoute, _createRoute 会调用 createRoute, createRoute 可以根据 record 和 location 创建出来,最终返回的是⼀条 Route 路径,。在 Vue-Router 中,所有的 Route 最终都会通过 createRoute 函数创建,并且它最后是不可以被外部修改的。

    Route 对象中有⼀个⾮常重要属性是 matched ,它通过formatMatch(record) 计算⽽来:

    可以看它是通过 record 循环向上找 parent ,只到找到最外层,并把所有的 record 都 push 到⼀个数组中,最终返回的就是 record 的数组,它记录了⼀条线路上的所有 record 。 matched属性⾮常有⽤,它为之后渲染组件提供了依据。


总结

    createMatcher: 根据路由的配置描述建立映射表,包括路径、名称到路由 record 的映射关系, 最重要的是 createRouteMap 这个方法,这里也是动态路由匹配和嵌套路由的原理。

    addRoutes: 动态添加路由配置

    match: 根据传入的 raw 和当前的路径 currentRoute 计算出一个新的路径并返回。

相关文章

  • VueRouter 对象

    VueRouter 的实现是⼀个类,首先看看constructor 构造函数。 其中 this.app 表示根 V...

  • VueRouter实现原理

    VueRouter类图 VueRouter类 属性: options:记录构造函数中传入的对象;路由规则route...

  • Vue基础-路由

    路由--按照path变换,router-view里面的组件变换 创建一个路由对象VueRouter({routes...

  • vue中$router和$route的区别

    1、$router对象 router是VueRouter的实例方法,相当于一个全局的路由器对象,作用是进行路由跳转...

  • 路由之章

    路由--按照path变换,router-view里面的组件变换 创建一个路由对象吧VueRouter({route...

  • vue $router和$route的区别

    一、router为VueRouter的实例,相当于一个全局的路由器对象,里面含有很多属性和子对象,例如histor...

  • vue-router

    1. router 引入VueRouter Vue.use(VueRouter)定义 (路由) 组件 cons...

  • Vue Router基础

    一、修改路口方法main.js1、引入VueRouter, import VueRouter from 'vue-...

  • VueRouter

    一、 vue-router是什么 这里的路由并不是指我们平时所说的硬件路由器,这里的路由就是SPA(单页应用)的...

  • vueRouter动态添加以及刷新404问题的解决

    技术栈: vue3,ts,vant,vueRouter4 vueRouter4中移除了addRouters,所以只...

网友评论

      本文标题:VueRouter 对象

      本文链接:https://www.haomeiwen.com/subject/eislpktx.html