VueRouter源码分析之install方法

307 阅读1分钟

VueRouter源码分析之install方法

vue插件使用第一步-Vue.use()

我们在vue项目中使用插件,首先需要用Vue.use()来注册插件。Vue.use()会寻找插件上的install方法,并执行。首次执行的时候,会给install上的installed赋值为true,代表注册了并继续向下执行。如果第二次来执行 当发现installedtrue,则直接return

VueRouter中如何使用vue内容

我们都知道,Vue.comonentVue.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)
    }
  })

这段代码意味着VueRouterinstall的时候混入了每一个Vue.comonentbeforeCreatedestroyed。对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时做了什么?

  1. 没有将vue打包进VueRouter中,而是使用函数传参的方式。
  2. mixin在组件的beforeCreate和destroyed对路由做了一些绑定。
  3. 所有组件的router使用的都是同一个VueRouter实例--根组件的router。
  4. 注册了RouterView与RouterLink
初学源码,有什么不对欢迎指出~~