vue-router源碼閱讀(一) 內部探究

1. 前言

vue-router版本:3.3.2javascript

vue-router倉庫:https://github.com/vuejs/vue-routerhtml

vue-router文檔:https://router.vuejs.org/zh/
vue

文章時間:2020-06-16java

 

2 執行順序

首先看個簡單的代碼塊,看看vue-router是怎麼註冊到vue實例上:git

// 1.註冊VueRouter
Vue.use(VueRouter);

// 2.建立路由組件並設置路由
const router = new VueRouter({
	mode: 'hash',
	routes: [
		{ path: '/', component: Home }
	]
});

// 3.建立Vue實例
window.vueInstance = new Vue({
	el: '#app',
	router
});

 

2.1 第一步:Vue.use(VueRouter)

調用此代碼時,實際執行的vue-router/src/install.js,其內部主要執行的代碼步驟以下:github

1) 設置Vue.prototype.$router屬性,返回值爲_router對象(全局VueRouter對象);web

2) 設置Vue.prototype.$route屬性,返回值爲_route對象(當前頁面的route對象);vue-router

3) 註冊全局組件:router-view;vuex

4) 註冊全局組件:router-link;緩存

5) 在Vue.beforeCreate事件上注入回調函數,此回調函數的執行在第三步 new Vue({router})上才觸發。

 

2.2 第二步:new VueRouter({options})

這一步是生成VueRouter對象,其調用的構造函數內部代碼執行步驟以下:

1) 建立this.matcher,進行以下操做:

  ①建立pathList:路由的全部path集合,並把'*'號路徑的路由移到pathList的最後。

  ②建立pathMap:key爲路由的path,item爲封裝了的對應的RouteRecord對象,包括path、path對應的regex、components、name等等。

  ③建立nameMap:key爲路由的name,item與pathMap同樣,都是RouteRecord對象。

  ④this.matcher提供了2個方法:match和addRoutes。

2) 建立this.history,此屬性根據options.mode設置不一樣的導航模式:

  ①若mode == 'history' :表示採用HTML5 History模式。

  ②若mode == 'hash' :表示採用hash模式,默認爲此模式。

  ③若mode == 'abstract' :支持全部 JavaScript 運行環境,如 Node.js 服務器端。

 

2.3 第三步:new Vue({ router })

這裏主要是爲了執行第一步的Vue.use(router)注入的beforeCreate回調。

其主要執行router.init()方法,內部步驟以下:

1) 當前router對象緩存建立的Vue實例

this.apps.push(app);
this.app = app;

2) 根據當前頁面的url獲取對應的Route對象並渲染匹配的組件頁面,其內部步驟以下:

  假設url爲http://localhost:8080/hash-mode/#/bar?a=1#title,model爲'hash'

  ①獲取路徑;值爲:/bar?a=1#title

  ②解析路徑,獲得路徑完整信息;值爲:{ hash: "#title", params: {}, path: "/bar", query: {a: "1"}, _normalized: true }

  ③根據上面的path,找到以前存儲的RouteRecord對象,建立爲Route對象。

  ④調用離開組件的beforeRouteLeave守衛;若當前的url改變是從組件a→組件b,這適合調用a組件的beforeRouteLeave守衛回調。

  ⑤調用全局Router的beforeEach守衛;

  ⑥調用重用組件裏的beforeRouteUpdate守衛;

  ⑦在路由配置裏調用beforeEnter守衛。

  ⑧對路由配置裏對應的異步組件進行解析;路由配置的組件經過 require.ensure() 或 Promise.resolve() 加載的組件纔會執行這一步。

  ⑨調用進入組件裏的beforeRouteEnter守衛;

  ⑩調用全局Router的beforeResolve守衛;

  ⑪導航被確認;修改當前的route爲新頁面的route;

  ⑫調用全局Router的afterEach守衛;

3) 在winodw的popstate事件上註冊回調,執行上一步操做( 執行第2步)。

注意:哪怕模式選擇的是'hash',當window擁有'popstate'事件時也會採用此事件,沒有的話才採用'hashchange'事件。爲何呢?由於'popstate'在IE上是不支持,'hashchange'從IE8開始支持。

4) 在Vue的destroyed鉤子註冊回調:註銷第4步在window註冊的回調。

 

 

相關文章
相關標籤/搜索