vue-router源码详解一

首发我的网站《锋言锋语》- vue-router源码详解一html

beforeCreate

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

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-router

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

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

参考资料:实例属性ide

所以只有在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属性:ui

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

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

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等路由操做函数。

相关文章
相关标签/搜索