成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

vue-router 實(shí)現(xiàn)分析

psychola / 3034人閱讀

摘要:而組件在創(chuàng)建時(shí),又怎么會(huì)去調(diào)用呢這是由于將自身作為一個(gè)插件安裝到了,通過注冊(cè)了一個(gè)鉤子函數(shù),從而在之后所有的組件創(chuàng)建時(shí)都會(huì)調(diào)用該鉤子函數(shù),給了檢查是否有參數(shù),從而進(jìn)行初始化的機(jī)會(huì)。

vue-router 是 Vue.js 官方的路由庫,本著學(xué)習(xí)的目的,我對(duì) vue-router 的源碼進(jìn)行了閱讀和分析,分享出來給其他感興趣的同學(xué)做個(gè)參考吧。

參考

源碼:vuejs/vue-router v2.2.1 - github

文檔:vue-router 官方中文教程

初步

我們分別從不同的視角來看 vue-router。

從開發(fā)者角度來看,是這樣的:

var router = new VueRouter({
  routes: [
   {path: "/foo", component: {template: "
FOO
"}}, {path: "/bar", component: {template: "
BAR
"}} ] }) var vm = new Vue({ el: "#app", router: router })

我們創(chuàng)建一個(gè) router,傳入的 routes 中的每一項(xiàng)即為一條路由(route)配置,表示在匹配給定的地址時(shí),應(yīng)該使用什么組件渲染視圖。

router 傳入 new Vue() 用于創(chuàng)建根組件,這樣根組件中對(duì)應(yīng)的視圖區(qū)域,可以基于 router 中的配置,根據(jù)頁面地址顯示不同的內(nèi)容。當(dāng)然,這還需要在組件模板中使用 來定義區(qū)域。

從視圖角度來看,是這樣的:

... ...

頁面地址變更后, 對(duì)應(yīng)的區(qū)域會(huì)更新為地址匹配的組件。例如,路徑是 /foo 則對(duì)應(yīng)區(qū)域顯示 FOO,路徑是 /bar 則顯示 BAR,路徑?jīng)]有匹配的組件時(shí),則不顯示內(nèi)容。

從數(shù)據(jù)角度來看,是這樣的:

vm
+ _router | $router
  - history
  - matcher
+ _route | $route
  - matched

vm.$router 引用當(dāng)前組件對(duì)應(yīng)的 router 對(duì)象,該對(duì)象在初始化時(shí)(在 vm 創(chuàng)建過程中執(zhí)行初始化),會(huì)啟動(dòng)對(duì)頁面地址變更的監(jiān)聽,從而在變更時(shí)更新 vm 的數(shù)據(jù)($route),進(jìn)而觸發(fā)視圖的更新。

深入

如何實(shí)現(xiàn)對(duì)地址變更的監(jiān)聽?

對(duì)于缺省的 HashHistory 模式(也就是基于頁面地址的 hash 部分來實(shí)現(xiàn)路由功能,如 http://example.com/path#/foohttp://example.com/path#/bar),是通過監(jiān)聽 hashChange 事件來實(shí)現(xiàn):

window.addEventListener("hashchange", () => {
  // this.transitionTo(...)
})

源碼

這個(gè)動(dòng)作是什么時(shí)候執(zhí)行的呢?

是在 router.init()(源碼)中調(diào)用的,而 router.init() 則是在根組件創(chuàng)建時(shí)(源碼)調(diào)用的。

而 Vue 組件在創(chuàng)建時(shí),又怎么會(huì)去調(diào)用 router.init() 呢?

這是由于 vue-router 將自身作為一個(gè)插件安裝到了 Vue,通過 Vue.mixin() 注冊(cè)了一個(gè) beforeCreate() 鉤子函數(shù),從而在之后所有的 Vue 組件創(chuàng)建時(shí)都會(huì)調(diào)用該鉤子函數(shù),給了檢查是否有 router 參數(shù),從而進(jìn)行初始化的機(jī)會(huì)。進(jìn)而通過層層調(diào)用執(zhí)行了監(jiān)聽 hashchange 事件的動(dòng)作。

整理一下:

new Vue()

執(zhí)行 vue-router 注入的 beforeCreate 鉤子函數(shù)

執(zhí)行 router.init(vm)

執(zhí)行 history.setupListeners(),注冊(cè)事件監(jiān)聽

地址變更如何通知到 vm?

這個(gè)過程比較簡單,hashchange 時(shí),執(zhí)行 history.transitionTo(...),在這個(gè)過程中,會(huì)進(jìn)行地址匹配,得到一個(gè)對(duì)應(yīng)當(dāng)前地址的 route,然后將其設(shè)置到對(duì)應(yīng)的 vm._route 上。

只是進(jìn)行了賦值,為什么 vm 就可以感知到路由的改變了呢?

答案在 vue-router 注入 Vue 的 beforeCreate 鉤子函數(shù)中(源碼):

Vue.util.defineReactive(this, "_route", this._router.history.current)

采用與 Vue 本身數(shù)據(jù)相同的“數(shù)據(jù)劫持”方式,這樣對(duì) vm._route 的賦值會(huì)被 Vue 攔截到,并且觸發(fā) Vue 組件的更新渲染流程。

地址變更如果同步視圖更新?

接上一步,vm._route 已經(jīng)接收到路由的變更,從而觸發(fā)視圖更新。而當(dāng)視圖更新進(jìn)一步調(diào)用到 render() 時(shí),即進(jìn)入了 的處理(源碼)。

render() 采用函數(shù)調(diào)用(h())模式,而非通過模板生成。這也是 Vue2 支持的定義組件渲染邏輯的方式,類似 React 的 render()。采用這種模式的好處是可以完全利用 JavaScript 的能力來編寫邏輯,不必受制于 Vue 的類 HTML 模板語法。

這里的主要處理邏輯是從根組件中取出當(dāng)前的路由對(duì)象(parent.$route),然后取得該路由下對(duì)應(yīng)的組件,然后交由該組件進(jìn)行渲染:

return h(component, data, children)

這其中還涉及 嵌套的處理,不過主要邏輯就是這樣了。

小結(jié)

其實(shí) vue-router 從 的實(shí)現(xiàn)來看,就是一個(gè)具有特定功能的 Vue 組件而已,不過要配合根組件的 router 發(fā)揮作用。但整體還是很“響應(yīng)式”的,也是蠻“Vue風(fēng)格”的。

vue-router 以插件方式“侵入”Vue,從而支持一個(gè)額外的 router 屬性,以提供監(jiān)聽并改變組件路由數(shù)據(jù)的能力。這樣每次路由發(fā)生改變后,可以同步到數(shù)據(jù),進(jìn)而“響應(yīng)式”地觸發(fā)組件的更新。

作為根組件下的子組件,從根組件那里可以獲取到當(dāng)前的路由對(duì)象,進(jìn)而根據(jù)路由對(duì)象的組件配置,取出組件并用其替換當(dāng)前位置的內(nèi)容。這樣,也就完成整個(gè)路由變更到視圖變更的過程。

路由變更到視圖變更的過程整理為:

hashchange
-->
match route
-->
set vm._route
-->
 render()
-->
render matched component

實(shí)現(xiàn)過程中的技術(shù)點(diǎn)包括:

Vue 插件機(jī)制

響應(yīng)式數(shù)據(jù)機(jī)制

Vue 渲染機(jī)制

地址變更監(jiān)聽

最后

我寫了一個(gè)應(yīng)用 Vue.js、vue-router 以及其他 Vue 相關(guān)工具(Vuex、vue-loader)的示例,感興趣可以看下:luobotang/vue-demo - github。

文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請(qǐng)注明本文地址:http://m.hztianpu.com/yun/88202.html

相關(guān)文章

  • 基于Vue,Vue-router,Vuex的簡書網(wǎng)站模仿

    摘要:本文假設(shè)讀者手里有關(guān)于和的文檔,并且對(duì)和有一定的了解。沒有文檔也沒關(guān)系我這里有關(guān)于文檔以及介紹,可以配合本文進(jìn)行學(xué)習(xí)。關(guān)鍵就是在中部導(dǎo)航欄熱門,新上榜那塊,棕色框內(nèi)的內(nèi)容會(huì)根據(jù)中部導(dǎo)航欄選中不同內(nèi)容進(jìn)行改變。 在這個(gè)教程里面,我會(huì)通過一系列的代碼和圖片來學(xué)習(xí)怎么使用vue-router,以及vuex。本文假設(shè)讀者手里有關(guān)于vue-router和Vuex的文檔,并且對(duì)Vue-router...

    warnerwu 評(píng)論0 收藏0
  • 基于Vue,Vue-router,Vuex的簡書網(wǎng)站模仿

    摘要:本文假設(shè)讀者手里有關(guān)于和的文檔,并且對(duì)和有一定的了解。沒有文檔也沒關(guān)系我這里有關(guān)于文檔以及介紹,可以配合本文進(jìn)行學(xué)習(xí)。關(guān)鍵就是在中部導(dǎo)航欄熱門,新上榜那塊,棕色框內(nèi)的內(nèi)容會(huì)根據(jù)中部導(dǎo)航欄選中不同內(nèi)容進(jìn)行改變。 在這個(gè)教程里面,我會(huì)通過一系列的代碼和圖片來學(xué)習(xí)怎么使用vue-router,以及vuex。本文假設(shè)讀者手里有關(guān)于vue-router和Vuex的文檔,并且對(duì)Vue-router...

    shiyang6017 評(píng)論0 收藏0
  • [使用 Weex 和 Vue 開發(fā)原生應(yīng)用] 6 使用 vue-router

    摘要:使用值來作路由。原生應(yīng)用本身就是多頁的場景,頁面間狀態(tài)的隔離比共享更重要一些。使用開發(fā)的是原生應(yīng)用,頁面棧的管理使用的也是原生的特性,沒有但是有模塊可以實(shí)現(xiàn)頁面的前進(jìn)和后退等操作。 系列文章的目錄在 ? 這里 (由于 我比較懶 最近一段時(shí)間在忙其他事,系列文章拖了好久終于又更新了。。。) 什么是 vue-router ? vue-router 官方文檔 vue-router 是針對(duì) V...

    leonardofed 評(píng)論0 收藏0

發(fā)表評(píng)論

0條評(píng)論

閱讀需要支付1元查看
<