beforeCreate

在src/install.js文件中使用Vue.mixi混入两个生命周期处理函数:beforeCreatedestroyed,在beforeCreate中处理了和rooter相关的操作:

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)
},

this.$options.router

vue中有两种vue对象:vue实例和vue组件,其中vue实例是通过new Vue创建的vue对象,vue组件是通过Vue.component创建的vue对象。 但是本质上“Vue组件是可复用的Vue实例”,而“vue实例是特殊的根vue组件”

参考资料:Vue 实例组件基础

vm.$options则是用于当前 Vue 实例的初始化选项。

参考资料:实例属性

因此只有在vue实例中,才传入了router属性:

import Vue from 'vue'
import VueRouter from 'vue-router'

Vue.use(VueRouter)

const router = new VueRouter({
  mode: 'history',
  routes: [...]
})

new Vue({
  router,
}).$mount('#app')

因此在beforeCreate中的代码,则是分别对根vue组件和普通vue组件做了_routerRoot的定义:

  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
  }

我们在组件中使用this.$router,就是返回_routerRoot_router属性:

  Object.defineProperty(Vue.prototype, '$router', {
    get () { return this._routerRoot._router }
  })

this.$route,就是返回_routerRoot_router属性:

  Object.defineProperty(Vue.prototype, '$route', {
    get () { return this._routerRoot._route }
  })

this.$routethis.$router区别

通过beforeCreate中的代码,可以得到:

  • this._router就是传入的router属性值,也就是new VueRouter返回的是VueRouter对象
  • this._routerRoot._route只是this._routerRoot._router中的history.current属性值

接下来,我们看一下this._router.history是一个什么对象呢?

export default class VueRouter {
  constructor (options: RouterOptions = {}) {
    let mode = options.mode || 'hash'

    switch (mode) {
      case 'history':
        this.history = new HTML5History(this, options.base)
        break
      case 'hash':
        this.history = new HashHistory(this, options.base, this.fallback)
        break
      case 'abstract':
        this.history = new AbstractHistory(this, options.base)
        break
      default:
        if (process.env.NODE_ENV !== 'production') {
          assert(false, `invalid mode: ${mode}`)
        }
    }
  }
}

通过VueRouter的构造函数可以看出,this._router.history在不同的场景下表示不同的对象,HTML5HistoryHashHistoryAbstractHistory对象。

上述三种***History类都继承于History类:

declare type Route = {
  path: string;
  name: ?string;
  hash: string;
  query: Dictionary<string>;
  params: Dictionary<string>;
  fullPath: string;
  matched: Array<RouteRecord>;
  redirectedFrom?: string;
  meta?: any;
}

export class History {
  current: Route
}

可以看出,this.$route也即this._routerRoot._route就是当前页面的url的一些基本属性,而this.$router则是代表整个vue router对象,所以更多的是使用起pushreplacego等路由操作函数。

Categories: JSvuejs前端

发表评论

电子邮件地址不会被公开。 必填项已用*标注