vue-router关于use和注入之间的细节

86 阅读1分钟
export function install (Vue) {
  if (install.installed && _Vue === Vue) return
  install.installed = true

  _Vue = Vue

  const isDef = v => v !== undefined

  const registerInstance = (vm, callVal) => {
    let i = vm.$options._parentVnode
    // 其实就是调用了 router-view 组件中的 registerRouteInstance 方法
    if (isDef(i) && isDef(i = i.data) && isDef(i = i.registerRouteInstance)) {
      i(vm, callVal)
    }
  }
  // 会全局混入
  Vue.mixin({
    beforeCreate () {
      // 所以new Vue({router})需要注入
      // 不然这里为false
      // 注入的目的,也是一个渠道获得vueRouter的实例
      if (isDef(this.$options.router)) {
        this._routerRoot = this
        this._router = this.$options.router
        this._router.init(this)
        // 添加一个属性_route值为this._router.history.current
        Vue.util.defineReactive(this, '_route', this._router.history.current)
      } else {
        // 后代组件从父组件那里一个个继承下来
        this._routerRoot = (this.$parent && this.$parent._routerRoot) || this
      }
      registerInstance(this, this)
    },
    destroyed () {
      registerInstance(this)
    }
  })
  // 每个实例才能this.$router访问到router
  Object.defineProperty(Vue.prototype, '$router', {
    get () { return this._routerRoot._router }
  })
 // 每个实例才能this.$route访问到route
 // 说明:Vue.util.defineReactive(this, '_route', this._router.history.current)
 // 虽然是第一次注入router的时候才会生成该属性,但
 // this._routerRoot 访问到的其实是注入时的那个router,因为后代组件都会一层层指向它
 // 所以也能访问到_route
 // 值为router.history.current
  Object.defineProperty(Vue.prototype, '$route', {
    get () { return this._routerRoot._route }
  })
 // 并且注册两个组件
  Vue.component('RouterView', View)
  Vue.component('RouterLink', Link)

  const strats = Vue.config.optionMergeStrategies
  // use the same hook merging strategy for route hooks
  strats.beforeRouteEnter = strats.beforeRouteLeave = strats.beforeRouteUpdate = strats.created
}
  • 总结 1、清楚use和注入各种的作用 2、清楚route和router的关系