VueRouter
在Vue组件中注册VueRouter
1
Vue.use(VueRouter)
定义(路由)组件
定义创建路由配置信息时所需要用到的组件。
创建VueRouter实例,并且配置路由匹配信息以及其他配置信息
1
2
3
4
5let router = new VueRouter({
routes: [
{path: '', name: '', component: componentName}
]
})Vue实例中挂载VueRouter实例
1
2
3new Vue({
router
})
路由注册
1. Vue.use(VueRouter)
只有在new Vue实例时,传入routers配置执行install才是有意义的。
Vue.use方法调用的是VueRouter中的install方法。VueRouter中install方法利用了Vue.mixin混入beforeCreate和destroyed钩子函数。
1 | Vue.mixin({ |
在Vue原型上挂载了$router, $route属性;注册了全局组件-RouterView和RouterLink;定义路由导航的合并策略-与vue的created钩子函数合并规则一致。
1 | // 挂载$router |
总结:
- Vue编写插件的时候需要提供静态的install方法
- VueRouter的install方法会给每个组件注入beforeCreate和destroyed钩子函数,在beforeCreate进行一些私有属性定义和路由初始化。
2. VueRouter、路由初始化
- init方法执行transitionTo方法做路由过渡
- 执行router.macth方法,此方法中执行matcher.match
路由初始化
1. 实例化VueRouter
new VueRouter会进入VueRouter类中的constructor构造器中。构造器接受一个配置项信息options对象,包含了路由配置信息routes,路由模式mode,降级处理fallback等。
- fallback:降级处理,对于路由模式的降级处理,如果不支持history就会降级到hash模式。
- 路由模式hash,history,abstract分别对应不同的类HashHistory,Html5History,AbstractHistory。这三个类都继承于history类。
1 | class VueRouter { |
创建路由映射表,方便以后根据path或者name查找到想要的record。并且对外提供了addRoutes(routes)方法,方便动态添加routes信息。
1 | function createMatcher (routes, router) { |
递归实例化VueRouter时传递的路由信息配置routes
1 | function addRouteRecord (pathList, pathMap, nameMap, route, parent, matchAs) { |
上面初始化一系列pathList,pathMap以及nameMap后,是为了方面后期的查找match【初始化开始beforeCreate=>init=>transitionTo=>router,match】,详情见下文。
2. 初始化开始:组件初始化阶段的beforeCreate-调用混入的router.init
Vue.use(VueRouter)之后混入了beforeCreate钩子函数执行时,会调用this._route.init(this)也就是调用VueRouter中的init方法。
1 | // VueRouter类中,app其实就是一个vue组件实例 |
transitionTo进行路由跳转
1 | transitionTo (location, onComplete) { |
获取当前路径this.router.match指向的是VueRouter中的match函数,match本质指向Matcher中的match函数。此match函数中利用到前面初始化的pathList,pathMap,nameMap数据。
1 | // VueRouter类中的match函数 |
Matcher中match函数,利用到前面初始化的pathList,pathMap,nameMap数据。此函数的作用:根据传递的location和当前route计算得出当前的路由。
1 | // Matcher中的match函数 |
会执行 _createRoute 函数,创建一个路由路径route。_createRoute会对record路径进行一系列的处理后,调用真正创建路由route的createRoute方法。
1 | function _createRoute (record, location, redirectedFrom) { |
createRoute创建路由,location指的是当前路径解析得到的数据对象,record则是指初始化路由routes时所保存初始的route配置相关信息,router是VueRoute实例。
1 | function createRoute (record, location, redirectedFrom, router) { |
总结:
- createMatcher的初始化就是根据路由的配置描述routes创建映射表(一个含有pathList,pathMap,nameMap对象),包含路径、名称到路由record的映射关系。
- match方法会根据传入的位置和路径计算出新的位置,并匹配到对应的路由route,然后根据新的位置和record创建新的路径route并返回。
路由切换
路由切换关系到导航守卫管理,URL变化,路由组件渲染等。路由切换主要就是上面有提到过的transitionTo,而transitionTo这个方法除了在初始化的时候有触发,也在VueRoute实例router的push和replace方法触发(HTML5History和HashHistory的push和replace方法)。
1. 开始:路由切换-transitionTo
1 | function transitionTo (location, onComplete, onAbort) { |
真正路由切换confirmTransition
1 | function confirmTransirionTo (route, onComplete, onAbort) { |
2. 导航守卫触发
在confirmTransition方法中,判断from和to不是相同路径后,会开始触发导航守卫
1 | function confirmTransition (route, onComplete, onAbort) { |
根据上面的代码逻辑,可以得到有关路由的守卫函数等的执行顺序是:组件beforeRouteLeave => 全局router.beforeEach => 组件beforeRouteUpdate => 路由配置routes的beforeEnter => 解析异步组件 => 组件beforeRouteEnter => 全局router.beforeResolve => 全局router.afterEach。