vue-router鉤子執(zhí)行順序示例解析
Vue路由執(zhí)行跳轉(zhuǎn)
Vue的路由在執(zhí)行跳轉(zhuǎn)時(shí),根據(jù)源碼可知,調(diào)用了router中定義的navigate函數(shù)
function push(to: RouteLocationRaw) {
return pushWithRedirect(to)
}
function replace(to: RouteLocationRaw) {
return push(assign(locationAsObject(to), { replace: true }))
}
function pushWithRedirect(
to: RouteLocationRaw | RouteLocation,
redirectedFrom?: RouteLocation
): Promise<NavigationFailure | void | undefined> {
// ...
return (failure ? Promise.resolve(failure) : navigate(toLocation, from))/*調(diào)用navigate*/
.catch((error: NavigationFailure | NavigationRedirectError) =>
isNavigationFailure(error)
? // navigation redirects still mark the router as ready
isNavigationFailure(error, ErrorTypes.NAVIGATION_GUARD_REDIRECT)
? error
: markAsReady(error) // also returns the error
: // reject any unknown error
triggerError(error, toLocation, from)
)
.then((failure: NavigationFailure | NavigationRedirectError | void) => {
if (failure) {
// ...
} else {
// 執(zhí)行finalizeNavigation完成導(dǎo)航
// if we fail we don't finalize the navigation
failure = finalizeNavigation(
toLocation as RouteLocationNormalizedLoaded,
from,
true,
replace,
data
)
}
// 觸發(fā)`afterEach`
triggerAfterEach(
toLocation as RouteLocationNormalizedLoaded,
from,
failure
)
return failure
})
}
function navigate(
to: RouteLocationNormalized,
from: RouteLocationNormalizedLoaded
): Promise<any> {
let guards: Lazy<any>[]
// ...
// run the queue of per route beforeRouteLeave guards
return (
// 1.調(diào)用離開組件的`beforeRouteLeave`鉤子
runGuardQueue(guards)
.then(() => {
// 獲取全局的的`beforeEach`鉤子
// check global guards beforeEach
guards = []
for (const guard of beforeGuards.list()) {
guards.push(guardToPromiseFn(guard, to, from))
}
guards.push(canceledNavigationCheck)
// 2.調(diào)用全局的`beforeEach`鉤子
return runGuardQueue(guards)
})
.then(() => {
// 獲取更新的路由其對(duì)應(yīng)組件的`beforeRouteUpdate`鉤子
// check in components beforeRouteUpdate
guards = extractComponentsGuards(
updatingRecords,
'beforeRouteUpdate',
to,
from
)
for (const record of updatingRecords) {
record.updateGuards.forEach(guard => {
guards.push(guardToPromiseFn(guard, to, from))
})
}
guards.push(canceledNavigationCheck)
// 3.調(diào)用復(fù)用組件的`beforeRouteUpdate`鉤子
// run the queue of per route beforeEnter guards
return runGuardQueue(guards)
})
.then(() => {
// 獲取進(jìn)入的路由自身的`beforeEnter`鉤子
// check the route beforeEnter
guards = []
for (const record of enteringRecords) {
// do not trigger beforeEnter on reused views
if (record.beforeEnter) {
if (isArray(record.beforeEnter)) {
for (const beforeEnter of record.beforeEnter)
guards.push(guardToPromiseFn(beforeEnter, to, from))
} else {
guards.push(guardToPromiseFn(record.beforeEnter, to, from))
}
}
}
guards.push(canceledNavigationCheck)
// 4.調(diào)用新匹配路由的`beforeEnter`鉤子
// run the queue of per route beforeEnter guards
return runGuardQueue(guards)
})
.then(() => {
// NOTE: at this point to.matched is normalized and does not contain any () => Promise<Component>
// clear existing enterCallbacks, these are added by extractComponentsGuards
to.matched.forEach(record => (record.enterCallbacks = {}))
// 獲取進(jìn)入的路由其對(duì)應(yīng)組件的`beforeRouteEnter`鉤子
// check in-component beforeRouteEnter
guards = extractComponentsGuards(
enteringRecords,
'beforeRouteEnter',
to,
from
)
guards.push(canceledNavigationCheck)
// 5.調(diào)用新組件的`beforeRouteEnter`鉤子
// run the queue of per route beforeEnter guards
return runGuardQueue(guards)
})
.then(() => {
// 獲取全局的的`beforeResolve`鉤子
// check global guards beforeResolve
guards = []
for (const guard of beforeResolveGuards.list()) {
guards.push(guardToPromiseFn(guard, to, from))
}
guards.push(canceledNavigationCheck)
// 6.調(diào)用全局的`beforeResolve`守衛(wèi)
return runGuardQueue(guards)
})
// catch any navigation canceled
.catch(err =>
isNavigationFailure(err, ErrorTypes.NAVIGATION_CANCELLED)
? err
: Promise.reject(err)
)
)
}
// 觸發(fā)`afterEach`
function triggerAfterEach(
to: RouteLocationNormalizedLoaded,
from: RouteLocationNormalizedLoaded,
failure?: NavigationFailure | void
): void {
// navigation is confirmed, call afterGuards
// TODO: wrap with error handlers
afterGuards
.list()
.forEach(guard => runWithContext(() => guard(to, from, failure)))
}順序執(zhí)行
由上述源碼中可以看出,由Promise then的鏈?zhǔn)秸{(diào)用保證了路由守衛(wèi)按照以下順序執(zhí)行:
- 舊的路由組件
beforeRouteLeave - 全局配置的
beforeEach - 復(fù)用的路由組件
beforeRouteUpdate - 新路由的
beforeEnter - 新路由組件的
beforeRouteEnter - 全局配置的
beforeResolve - navigate執(zhí)行完畢后,會(huì)調(diào)用
triggerAfterEach函數(shù),觸發(fā)afterEach
和官網(wǎng)文檔上所寫的是一樣的。The Full Navigation Resolution Flow
以上就是vue-router鉤子執(zhí)行順序的詳細(xì)內(nèi)容,更多關(guān)于vue-router鉤子執(zhí)行順序的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
創(chuàng)建項(xiàng)目及包管理yarn create vite源碼學(xué)習(xí)
這篇文章主要為大家介紹了創(chuàng)建項(xiàng)目及包管理yarn create vite源碼學(xué)習(xí)分析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
基于Vue和Element-Ui搭建項(xiàng)目的方法
這篇文章主要介紹了基于Vue和Element-Ui搭建項(xiàng)目的方法,本文給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-09-09
Vue.js實(shí)現(xiàn)高質(zhì)量翻頁功能的完整開發(fā)指南
當(dāng)我們?cè)诰W(wǎng)頁中展示大量數(shù)據(jù)時(shí),分頁能幫助用戶快速瀏覽內(nèi)容,提高頁面的加載性能和用戶體驗(yàn),本文將從基礎(chǔ)翻頁功能入手,逐步升級(jí)至可復(fù)用的分頁組件,并提供性能優(yōu)化和用戶體驗(yàn)提升的實(shí)用建議,需要的朋友可以參考下2025-07-07
Vue3封裝自動(dòng)滾動(dòng)列表指令(含網(wǎng)頁縮放滾動(dòng)問題)
本文主要介紹了Vue3封裝自動(dòng)滾動(dòng)列表指令(含網(wǎng)頁縮放滾動(dòng)問題),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
vue2.0 兄弟組件(平級(jí))通訊的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue2.0 兄弟組件(平級(jí))通訊的實(shí)現(xiàn)代碼,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下2018-01-01
如何使用crypto-js對(duì)文件上傳下載進(jìn)行加密處理
這篇文章主要介紹了如何使用crypto-js對(duì)文件上傳下載進(jìn)行加密處理方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05
windows下vue-cli及webpack搭建安裝環(huán)境
這篇文章主要介紹了windows下vue-cli及webpack搭建安裝環(huán)境,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-04-04
Vue實(shí)現(xiàn)側(cè)邊導(dǎo)航欄于Tab頁關(guān)聯(lián)的示例代碼
本文主要介紹了Vue實(shí)現(xiàn)側(cè)邊導(dǎo)航欄于Tab頁關(guān)聯(lián)的示例代碼,文中通過示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2021-11-11
Vue中mintui的field實(shí)現(xiàn)blur和focus事件的方法
今天小編就為大家分享一篇Vue中mintui的field實(shí)現(xiàn)blur和focus事件的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2018-08-08

