前言
vue-router是Vue项目中组件化的核心,负责路由跳转,本系列会分析路由跳转的具体实现逻辑,目标是梳理路由跳转的实现逻辑。分析的版本是VueRouter最新版本,是build之后的vue-router.js文件。
具体分析
从简单实例出发分析整个流程:
html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Document</title>
<script src="https://unpkg.com/vue/dist/vue.js"></script>
<script src="./vue-router.js"></script>
</head>
<body>
<div id="app">
<h1>Hello App!</h1>
<p>
<router-link to="/foo">Go to Foo</router-link>
<router-link to="/bar">Go to Bar</router-link>
</p>
<router-view></router-view>
</div>
<script>
const Foo = { template: '<div>foo</div>' }
const Bar = { template: '<div>bar</div>' }
// 定义路由跳转关系
const routes = [
{ path: '/foo', component: Foo },
{ path: '/bar', component: Bar }
]
// 定义路由对象
const router = new VueRouter({
routes
})
// 将router注册到Vue中
const app = new Vue({
router
}).$mount('#app')
</script>
</body>
</html>
效果:
通过script标签来加载解析vue-router文件,解析执行vue-router发生了什么呢?这是接下来需要分析的。
VueRouter解析过程
vue-router文件在加载解析过程中处理逻辑如下:
实际vue-router文件解析的过程做的主要事情有四点:
- 定义router-view组件
- 定义router-link组件
- 创建初始路由Route对象
- 满足浏览器环境以及Vue存在,就执行Vue.use(VueRouter)
- 暴露VueRouter
Vue插件的使用方式就是Vue.use(插件),此时会调用插件中的install方法
所以Vue.use(VueRouter)实际上是调用VueRouter中的install方法,通过源码可知:
VueRouter.install = install;
接下来就具体分析install函数的逻辑。
install
install是创建的初始化过程,它的具体处理逻辑如下:
install函数中逻辑主要点有如下几点:
- 保证初始化的唯一性
- 混入beforeCreate和destroyed生命周期函数
- 定义并监听router、router、route属性
- 在Vue.config.optionMergeStrategies上自定义beforeRouteEnter、beforeRouteLeave、beforeRouteUpdate混入,使用created的混入策略
实际上最主要是第二条,在beforeCreate生命周期函数中的处理逻辑:
if (isDef(this.$options.router)) {
this._routerRoot = this;
this._router = this.$options.router;
this._router.init(this);
Vue.util.defineReactive(this, '_route', this._router.history.current);
} else {
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this;
}
registerInstance(this, this);
- 首先判断new Vue()实例中是否存在router属性, 在解析的时候还没有new Vue()所以此处为false
- 存在就:
- 设置router根实例是当前实例
- 设置_router属性值为VueRouter实例对象
- 调用实例对象的init(),进行初始化
- 使用Vue.util中的defineReactive定义this对象的响应属性_route为当前路由模块
- 不存在:就判断是否存在父组件,存在就将父组件中的_routeRoot赋值为当前实例的_routerRoot
- 注册实例
总结
在vue-router初始化的过程中可以看到,实现上主要的工作就几点:
-
全局注册router-view、router-link组件
-
使用Vue.mixin往所有组件中混入beforeCreate、destroyed生命周期函数
-
beforeRouteLeave、beforeRouteEnter、beforeRouteUpdate自定义混合到组件中,混合策略与created相同
-
暴露VueRouter构造函数
下一篇文章主要分析new VueRouter的过程。
————————————————
智一面|前端面试必备练习题