VueRouter源码分析之install方法
vue插件使用第一步-Vue.use()
我们在vue项目中使用插件,首先需要用Vue.use()来注册插件。Vue.use()会寻找插件上的install方法,并执行。首次执行的时候,会给install上的installed赋值为true,代表注册了并继续向下执行。如果第二次来执行 当发现installed为true,则直接return。
VueRouter中如何使用vue内容
我们都知道,Vue.comonent、Vue.mixin都是vue的方法,想要在VueRouter中使用vue的话,就必须要引入vue。然后这会造成VueRouter的包很大。且源码中也是没有直接引入vue的。源码中是在install的时候使用全局的vue。
//声明一个私有变量,用来接受外部的vue类
export let _Vue
//接受一个vue的传参
export function install (Vue) {
//如果已经注册了,并且_vue也已经被赋值,则直接return
if (install.installed && _Vue === Vue) return
install.installed = true
//将vue赋值给_vue
_Vue = Vue
mixin混入
Vue.mixin({
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)
},
destroyed () {
registerInstance(this)
}
})
这段代码意味着VueRouter在install的时候混入了每一个Vue.comonent的beforeCreate和destroyed。对router进行了一些绑定。
谁有router
//this.$options.router 是绑定在 app根节点的组件上的,所有只有这个组件有router
Vue.mixin({
beforeCreate () {
//判断根节点上是否有router
if (isDef(this.$options.router)) {
//_routerRoot代表app根节点 组件
this._routerRoot = this
//绑定router
this._router = this.$options.router
this._router.init(this)
//变成响应式
Vue.util.defineReactive(this, '_route', this._router.history.current)
} else {
//如果this上没有router,说明他不是根节点,或者他是根节点,但未绑定
//不是根节点就找他的parent,是根节点就还是自己
//所以大家都是用同一个属性,每一个组件的_routerRoot都是根组件
this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
}
registerInstance(this, this)
},
destroyed () {
registerInstance(this)
}
})
Object.defineProperty(Vue.prototype, '$router', {
get () { return this._routerRoot._router }
})
Object.defineProperty(Vue.prototype, '$route', {
get () { return this._routerRoot._route }
})
以上,通过Object.defineProperty,在vue原型上绑定了$router,证明了我们在vue中使用this.$router其实用的都是同一个router,都是根组件的router
RouterView与RouterLink注册
Vue.component('RouterView', View)
Vue.component('RouterLink', Link)
总结
VueRouter在install时做了什么?
- 没有将vue打包进VueRouter中,而是使用函数传参的方式。
- mixin在组件的beforeCreate和destroyed对路由做了一些绑定。
- 所有组件的router使用的都是同一个VueRouter实例--根组件的router。
- 注册了RouterView与RouterLink