首发我的网站《锋言锋语》- vue-router源码详解一html
在src/install.js文件中使用Vue.mixi
混入两个生命周期处理函数:beforeCreate
和destroyed
,在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) },
vue中有两种vue
对象:vue实例和vue组件,其中vue实例是经过new Vue
建立的vue
对象,vue组件是经过Vue.component
建立的vue
对象。
可是本质上“Vue组件是可复用的Vue实例”,而“vue实例是特殊的根vue组件”vue-router
而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.$route
和this.$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
在不一样的场景下表示不一样的对象,HTML5History
、HashHistory
或AbstractHistory
对象。
上述三种***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
对象,因此更多的是使用起push
、replace
、go
等路由操做函数。