首發我的網站《鋒言鋒語》- 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
等路由操做函數。