vue-router源碼解讀--路由過渡

目錄導(dǎo)航

經(jīng)過上一節(jié)分析我們知道,vueRouter在初始化的最后一步執(zhí)行了transitionTo進(jìn)行路由過渡

這一節(jié)我們將嘗試分析,路由過渡過程中都做了哪些事情

該函數(shù)的入?yún)閔istory.getCurrentLocation的返回值、

函數(shù)

history.getCurrentLocation在history和hash模式下對(duì)應(yīng)的引用不同

history

通過location對(duì)象的pathname屬性獲取當(dāng)前瀏覽器的url地址,如vue官網(wǎng)地址為https://cn.vuejs.org/v2/guide/components-slots.html,則得到的path為/v2/guide/components-slots.html

base是再路由中配置的,這在history模式中解決刷新404時(shí)有用,當(dāng)前未作配置,跳過

最后通過window.location.search獲取?后的文本url,如http://www.baidu.com?aaa=1,則匹配到?aaa=1;通過window.location.hash取到我們的hast值,如http://www.baidu.com?aaa=1#head,則匹配#head。那么最終返回的值為http://www.baidu.com?aaa=1#head

hash

通過window.location.href拿到路徑,對(duì)應(yīng)history的結(jié)果,一樣為http://www.baidu.com?aaa=1#head

最后將hash值截取掉,即http://www.baidu.com?aaa=1

也就是說,不論哪種模式,返回是http://www.baidu.com?aaa=1

setupListeners函數(shù)

這在執(zhí)行時(shí)將回調(diào)history.setupListeners函數(shù)

history

通過對(duì)popstate的監(jiān)聽以觀測(cè)url的變化,將觸發(fā)回調(diào)handleRoutingEvent,重新執(zhí)行過渡

hash

通過對(duì)hashchange的監(jiān)聽以觀測(cè)url的變化,將觸發(fā)回調(diào)handleRoutingEvent,重新執(zhí)行過渡

也就是說,不論是history還是hash模式都將最終執(zhí)行到this.transitionTo函數(shù),入?yún)楫?dāng)前頁面url地址、回調(diào)函數(shù)、undefined


首先通過router.match拿到route定義,即調(diào)用vueRouter的match函數(shù),入?yún)閡rl地址、當(dāng)前的record對(duì)象,undefined

因此,在路由過渡之前,將生成一個(gè)當(dāng)前路徑的路由對(duì)象

回到this.transitionTo,調(diào)用confirmTransition,傳入路由對(duì)象(將要激活的路由)

框紅一的位置,拿到我們當(dāng)前正在激活和路由和上一次的路由

框紅二的位置,對(duì)新舊路由進(jìn)行比對(duì),如果是同一個(gè),則調(diào)用ensureURL,這最終將調(diào)用history.pushState,修改hisotry對(duì)象和地址欄,但是頁面內(nèi)容不改變,也不會(huì)觸發(fā)popstate事件

框紅三的位置

? ? ? ? 首先調(diào)用resolveQueue,傳入當(dāng)前和上一次的路由對(duì)象中保存的metched,這實(shí)際上指向的是在路由映射表中保存的record,假設(shè)本次操作是從/foo——>/info

? ? ? ? 則current為

? ? ? ? next為

? ? ? ? resolveQueue函數(shù)

????????通過Math.max取最大值,然后遍歷找不相等。當(dāng)由一個(gè)一級(jí)路由跳轉(zhuǎn)到二級(jí)子路由的時(shí)候,實(shí)際上next會(huì)有兩個(gè),比如從/info跳轉(zhuǎn)到/info/child時(shí),此時(shí)next為['/info的record','/info/child的record'],我們需要通過遍歷找出不相等的哪一個(gè),即跳過/foo

? ? ? ? 那么返回的updated則標(biāo)識(shí)上一次舊路由,即/info;activated標(biāo)識(shí)新路由,即/foo/child,deactivated則標(biāo)識(shí)失效的路由,顯然只要i有值,則標(biāo)識(shí)null

返回的框紅三的位置

? ? ? ? 定義queue,這是一個(gè)一維數(shù)組,這里保存著所有的導(dǎo)航鉤子,如beforeEach、afterEach、beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave

? ? ? ? 定義iterator迭代器

? ? ? ? 可以看出,這里實(shí)際上對(duì)應(yīng)的就是我們的導(dǎo)航守衛(wèi),將在runQueue時(shí)被執(zhí)行(也就是說該方法是用來跑我們?cè)诼酚芍信渲玫氖匦l(wèi)用的)

? ? ? ? 框紅的onComplete為

? ? ? ? 調(diào)用updateRoute將當(dāng)前正則激活的路由更新為當(dāng)前路由;再次執(zhí)行一次setupListeners對(duì)當(dāng)前url進(jìn)行監(jiān)聽,因?yàn)榕f路由對(duì)應(yīng)的組件被銷毀時(shí),popstate或hashchange也被相應(yīng)的移除


因此,路由過渡的核心是通過監(jiān)聽popstate或hashchange事件回調(diào)執(zhí)行transitionTo,并在transitionTo過程中完成鉤子函數(shù)的調(diào)用(runQueue)及瀏覽器歷史記錄的修正(pushState),以達(dá)到視圖的更新

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容