对于 Vue Router 源码的解析
时间守卫 路由更新原理 路由查找原理
Vue-Router
Vue-Router 是 vue 的路由插件,能够方便我们进行路由管理,是单页面开发不可或缺的一部分。vue-router 使用相对简单,编码格式化合理,能够极大地帮助我们开发单页面应用。
tips:本文不讲解 vue-router 的基本使用,只对源码进行解析
vue-router 官方指导网站:点我
源码结构以及状态图
vue-router 源码文件较多,但有部分是功能性模块,层次分明
关键文件解析:
1 | 源码结构: |
原理结构图:
install.js
对于 Vue 插件,都是通过 Vue 实例创建调用 install.js 文件进行安装,而 vue-router 的 install 主要完成了 5 件事:
1 | * Vue.use(插件)来注册插件的时候会找到插件的install方法进行执行 |
源码如下:
1 | import View from "./components/view"; |
可以看到,install 时运用了 Vue 的响应式劫持_route,以确保路由变化时能够调用 render 更新 router-view 组件,同时再通过 Object.defineProperty 在 Vue 的原型上设置 router 和 route,使得所有 vue 组件可以访问。而在混入的 beforeCreate 一开始对 options.router 进行判断,判断是否是根 Vue 实例,如果不是则去根 vue 实例中获取 routeRoot,确保所有 vue 实例共用一个路由器。
class VueRouter
接着,我们看看 VueRouter 内部是怎样实现路由管理的。
首先,Vue.use()会调用构造函数,生成必须的变量,并且根据 mode 选项生成对应的 History 管理器:
1 | // 构造函数 |
然后我们再看到 install 时调用的 init 方法,初始化需要通过这一方法第一次确定路由,渲染视图,因此我们可以通过它看到基本的过程:
1 |
|
可以看到,在 init 中,把所有调用它的 app 也就是 vue 实例,放到了 this.apps 数组中,并且监听他们的 destroyed 声明周期。然后判断是不是根 vue 实例,如果是,则根据前面构造函数确定的 history,调用方法获取当前 location,然后再调用 transitionTo 做路由切换。
base.js
那我们再看到 history/base.js 中定义的 transitionTo,confirmTransition,updateRoute,是怎么做到路由的切换的。
1 | // transitionTo 首先根据目标 location 和当前路径 this.current 执行 this.router.match 方法去匹配到目标的路径 |
transitionTo 中调用的 match 方法定义在了 index.js 中
1 | // 输入参数raw,current,redirectedForm,结果返回匹配 route |
可以看到,先通过 match 方法匹配出新路由的路径,然后在 confirmTransition 中与旧路径做对比,如果不同,则根据两个路径解析出三个队列分别表示更新路径,新增路径,消灭路径,对应方法如下:
1 | /** |
拿到 updated、activated、deactivated 3 个 RouteRecord 数组后,接下来就是执行一系列的钩子函数,最后再是调用 updateRoute 更新 history.current 属性,触发根组件的_route 的变化,最后更新视图。
向外暴露的方法
vue-router 同时向外部暴露一些方法供开发者扩展,比如添加钩子函数,主动跳转路由等,定义如下
1 | /** |
结语
小结:
1 | 路由更新方法: |
本文仅分析了源码中最为核心的部分,很多如递归路由,不同路由模式 history 的异同等,都没有分析,也欢迎大家和我一起讨论学习
编者 github 地址:传送
qq:1073490398
wechat:carfiedfeifei