一、vue-router有幾種鉤子函數(shù)?具體是什么及其參數(shù)
? ? 1、全局路由。(全局導(dǎo)航鉤子主要有兩種鉤子:前置守衛(wèi)、后置鉤子。)
? ??????注冊(cè)一個(gè)全局前置守衛(wèi):beforeEach;
const router = new VueRouter({ ... });
router.beforeEach((to, from, next) => {
? ?? // do someting
});
這三個(gè)參數(shù) to 、from 、next 分別的作用:
? ? 1、to: Route,代表要進(jìn)入的目標(biāo),它是一個(gè)路由對(duì)象;
? ? 2、from: Route,代表當(dāng)前正要離開的路由,同樣也是一個(gè)路由對(duì)象;
? ? 3、next: Function,這是一個(gè)必須需要調(diào)用的方法,而具體的執(zhí)行效果則依賴 next 方法調(diào)用的參數(shù);
????????next參數(shù)須知:
????????????next():進(jìn)入管道中的下一個(gè)鉤子,如果全部的鉤子執(zhí)行完了,則導(dǎo)航的狀態(tài)就是 confirmed(確認(rèn)的);
????????????next(false):這代表中斷掉當(dāng)前的導(dǎo)航,即 to 代表的路由對(duì)象不會(huì)進(jìn)入,被中斷,此時(shí)該表 URL 地址會(huì)被重置到 from 路由對(duì)應(yīng)的地址;
? ??????????next(‘/’) 和 next({path: ‘/’}):在中斷掉當(dāng)前導(dǎo)航的同時(shí),跳轉(zhuǎn)到一個(gè)不同的地址;
? ??????????next(error):如果傳入?yún)?shù)是一個(gè) Error 實(shí)例,那么導(dǎo)航被終止的同時(shí)會(huì)將錯(cuò)誤傳遞給 router.onError() 注冊(cè)過的回調(diào);
注意:next 方法必須要調(diào)用,否則鉤子函數(shù)無法 resolved;
? ??????全局后置鉤子:afterEach;
router.afterEach((to, from) => {
? ?? // do someting
});
注意:不同于前置守衛(wèi),后置鉤子并沒有 next 函數(shù),也不會(huì)改變導(dǎo)航本身
? ??2. 路由獨(dú)享的鉤子
? ??顧名思義,即單個(gè)路由獨(dú)享的導(dǎo)航鉤子,它是在路由配置上直接進(jìn)行定義的:
cont router = new VueRouter({
? ??routes: [
? ? ? ? {
? ??????????path: '/file',
? ??????????component: File,
? ??????????beforeEnter: (to, from ,next) => {?
? ??????????????// do someting?
? ? ? ? ? ? }
? ? ? ? }
? ? ]
});
注意:參數(shù)的使用,和全局前置守衛(wèi)是一樣的
3. 組件內(nèi)的導(dǎo)航鉤子
? ??組件內(nèi)的導(dǎo)航鉤子主要有這三種:beforeRouteEnter、beforeRouteUpdate、beforeRouteLeave。他們是直接在路由組件內(nèi)部直接進(jìn)行定義的。
????具體用法:
const File = {
? ??template: `<div>This is file</div>`,
? ??beforeRouteEnter(to, from, next) {
? ??????// do someting
? ??????// 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用
? ??},
? ??beforeRouteUpdate(to, from, next) {
? ??????// do someting
? ??????// 在當(dāng)前路由改變,但是依然渲染該組件是調(diào)用?
? ? },
? ??beforeRouteLeave(to, from ,next) {
? ??????// do someting
? ??????// 導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)被調(diào)用
? ? }
}
注意:beforeRouteEnter 不能獲取組件實(shí)例 this,因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例被沒有被創(chuàng)建出來,剩下兩個(gè)鉤子則可以正常獲取組件實(shí)例 this
但是并不意味著在 beforeRouteEnter 中無法訪問組件實(shí)例,我們可以通過給 next 傳入一個(gè)回調(diào)來訪問組件實(shí)例。在導(dǎo)航被確認(rèn)是,會(huì)執(zhí)行這個(gè)回調(diào),這時(shí)就可以訪問組件實(shí)例了,如:
beforeRouteEnter(to, from, next) {
? ??next (vm => {
? ??????// 這里通過 vm 來訪問組件實(shí)例解決了沒有 this 的問題
? ??})
}
注意,僅僅是 beforRouteEnter 支持給 next 傳遞回調(diào),其他兩個(gè)并不支持。因?yàn)闅w根結(jié)底,支持回調(diào)是為了解決 this 問題,而其他兩個(gè)鉤子的 this 可以正確訪問到組件實(shí)例,所有沒有必要使用回調(diào)
最后是完整的導(dǎo)航解析流程:
? ? 1、導(dǎo)航被觸發(fā)
? ? 2、在失活的組件里調(diào)用離開守衛(wèi)
? ? 3、調(diào)用全局的 beforeEach 守衛(wèi)
? ? 4、在重用的組件里調(diào)用 beforeRouteUpdate 守衛(wèi)
? ? 5、在路由配置里調(diào)用 beforEnter
? ? 6、解析異步路由組件
? ? 7、在被激活的組件里調(diào)用 beforeRouteEnter
? ? 8、調(diào)用全局的 beforeResolve 守衛(wèi)
? ? 9、導(dǎo)航被確認(rèn)
? ? 10、調(diào)用全局的 afterEach 鉤子
? ? 11、觸發(fā) DOM 更新
? ? 12、在創(chuàng)建好的實(shí)例調(diào)用 beforeRouteEnter 守衛(wèi)中傳給 next 的回調(diào)函數(shù)