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


1. 前言

vue-router版本:3.3.2

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

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

文章時間:2020-06-16

 

2 執行順序

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

// 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,其內部主要執行的代碼步驟如下:

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

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

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

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注冊的回調。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM