路由守衛(wèi)是什么?
官方解釋:
“導(dǎo)航”表示路由正在發(fā)生改變。正如其名,vue-router提供的導(dǎo)航守衛(wèi)主要用來通過跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航。有多種機(jī)會(huì)植入路由導(dǎo)航過程中:全局的, 單個(gè)路由獨(dú)享的, 或者組件級(jí)的。
簡(jiǎn)單的說,導(dǎo)航守衛(wèi)就是路由跳轉(zhuǎn)過程中的一些鉤子函數(shù)。路由跳轉(zhuǎn)是一個(gè)大的過程,這個(gè)大的過程分為跳轉(zhuǎn)前中后等等細(xì)小的過程,在每一個(gè)過程中都有一函數(shù),這個(gè)函數(shù)能讓你操作一些其他的事兒,這就是導(dǎo)航守衛(wèi)。類似于組件生命周期鉤子函數(shù)
路由守衛(wèi)分類
【1】全局守衛(wèi):是指路由實(shí)例上直接操作的鉤子函數(shù),特點(diǎn)是所有路由配置的組件都會(huì)觸發(fā),直白點(diǎn)就是觸發(fā)路由就會(huì)觸發(fā)這些鉤子函數(shù)
- beforeEach(to,from, next)
- beforeResolve(to,from, next)
- afterEach(to,from)
【2】路由守衛(wèi):是指在單個(gè)路由配置的時(shí)候也可以設(shè)置的鉤子函數(shù)
- beforeEnter(to,from, next)
【3】組件守衛(wèi):是指在組件內(nèi)執(zhí)行的鉤子函數(shù),類似于組件內(nèi)的生命周期,相當(dāng)于為配置路由的組件添加的生命周期鉤子函數(shù)。
- beforeRouteEnter(to,from, next)
- beforeRouteUpdadte(to,from, next)
- beforeRouteLeave(to,from, next)
路由守衛(wèi)回調(diào)參數(shù)介紹
to:即將要進(jìn)入的目標(biāo)路由對(duì)象;
from:即將要離開的路由對(duì)象;
next:涉及到next參數(shù)的鉤子函數(shù),必須調(diào)用next()方法來resolve這個(gè)鉤子,否則路由會(huì)中斷在這,不會(huì)繼續(xù)往下執(zhí)行
- next():進(jìn)行管道中的下一個(gè)鉤子。如果全部鉤子執(zhí)行完了,則導(dǎo)航的狀態(tài)就是confirmed(確認(rèn)的)。
- next( false )中斷當(dāng)前的導(dǎo)航。如果瀏覽器的 URL 改變了 (可能是用戶手動(dòng)或者瀏覽器后退按鈕),那么 URL 地址會(huì)重置到from路由對(duì)應(yīng)的地址。
- next( ' / ')或者next({ paht:' / ' }):跳轉(zhuǎn)到一個(gè)不同的地址。當(dāng)前的導(dǎo)航被中斷,然后進(jìn)行一個(gè)新的導(dǎo)航??蓚鬟f的參數(shù)可以是router-link標(biāo)簽中的to屬性參數(shù)或router.push中的選項(xiàng)
- next( error ):如果傳入next的參數(shù)是一個(gè)Error實(shí)例,則導(dǎo)航會(huì)被終止且該錯(cuò)誤會(huì)被傳遞給router.onError()注冊(cè)過的回調(diào)。
路由守衛(wèi)詳解
【1】全局前置守衛(wèi)(beforeEach): 在路由跳轉(zhuǎn)前觸發(fā),這個(gè)鉤子作用主要是用于登錄驗(yàn)證,也就是路由還沒跳轉(zhuǎn)提前告知,以免跳轉(zhuǎn)了再通知就為時(shí)已晚。
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
【2】全局解析守衛(wèi)(beforeResolve): 這個(gè)鉤子和beforeEach類似,也是路由跳轉(zhuǎn)前觸發(fā),區(qū)別是在導(dǎo)航被確認(rèn)之前,同時(shí)在所有組件內(nèi)守衛(wèi)和異步路由組件被解析之后,即在 beforeEach 和 組件內(nèi)beforeRouteEnter 之后,afterEach之前調(diào)用。
【3】全局后置鉤子(afterEach): 和beforeEach相反,它是在路由跳轉(zhuǎn)完成后觸發(fā),它發(fā)生在beforeEach和beforeResolve之后,beforeRouteEnter(組件內(nèi)守衛(wèi))之前。這些鉤子不會(huì)接受next函數(shù)也不會(huì)改變導(dǎo)航本身
router.afterEach((to, from) => {
// ...
})
【4】路由獨(dú)享守衛(wèi)(beforeEnter): 和beforeEach完全相同,如果兩個(gè)都設(shè)置了,beforeEnter則在beforeEach之后緊隨執(zhí)行。在路由配置上直接定義beforeEnter守衛(wèi)
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
【5】組件內(nèi)的守衛(wèi):
<template>
...
</template>
<script>
export default{
data(){
//...
},
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對(duì)應(yīng)路由被 confirm 前調(diào)用
// 不!能!獲取組件實(shí)例 `this`
// 因?yàn)楫?dāng)守衛(wèi)執(zhí)行前,組件實(shí)例還沒被創(chuàng)建
},
beforeRouteUpdate (to, from, next) {
// 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用
// 舉例來說,對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉(zhuǎn)的時(shí)候,
// 由于會(huì)渲染同樣的 Foo 組件,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用。
// 可以訪問組件實(shí)例 `this`
},
beforeRouteLeave (to, from, next) {
// 導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)調(diào)用
// 可以訪問組件實(shí)例 `this`
}
}
</script>
<style>
...
</style>
1. beforeRouteEnter:該鉤子在全局守衛(wèi)beforeEach和獨(dú)享守衛(wèi)beforeEnter之后,全局beforeResolve和全局afterEach之前調(diào)用,要注意的是該守衛(wèi)內(nèi)訪問不到組件的實(shí)例,也就是this為undefined。因?yàn)樗诮M件生命周期beforeCreate階段觸發(fā),此時(shí)的新組件還沒有被創(chuàng)建。在這個(gè)鉤子函數(shù)中,可以通過傳一個(gè)回調(diào)給 next來訪問組件實(shí)例。在導(dǎo)航被確認(rèn)的時(shí)候執(zhí)行回調(diào),并且把組件實(shí)例作為回調(diào)方法的參數(shù)。
beforeRouteEnter (to, from, next) {
next(vm => {
// 通過 `vm` 訪問組件實(shí)例
})
}
2. beforeRouteUpdadte:在當(dāng)前路由改變時(shí),并且該組件被復(fù)用時(shí)調(diào)用,可以通過this訪問實(shí)例。
3. beforeRouteLeave:導(dǎo)航離開該組件的對(duì)應(yīng)路由時(shí)調(diào)用,可以訪問組件實(shí)例this。這個(gè)離開守衛(wèi)通常用來禁止用戶在還未保存修改前突然離開。該導(dǎo)航可以通過next( false )來取消。
beforeRouteLeave (to, from , next) {
const answer = window.confirm('Do you really want to leave? you have unsaved changes!')
if (answer) {
next()
} else {
next(false)
}
}
完整的導(dǎo)航解析流程
- 觸發(fā)進(jìn)入其它路由
- 調(diào)用要離開路由的組件守衛(wèi)beforeRouteLeave
- 調(diào)用全局的前置守衛(wèi)beforeEach
- 在重用的組件里調(diào)用 beforeRouteUpdate
- 在路由配置里調(diào)用 beforeEnter
- 解析異步路由組件
- 在將要進(jìn)入的路由組件中調(diào)用beforeRouteEnter
- 調(diào)用全局的解析守衛(wèi)beforeResolve
- 導(dǎo)航被確認(rèn)
- 調(diào)用全局的后置鉤子afterEach。
- 觸發(fā) DOM 更新mounted。
- 執(zhí)行beforeRouteEnter守衛(wèi)中傳給 next的回調(diào)函數(shù)。

文章每周持續(xù)更新,可以微信搜索「 前端大集錦 」第一時(shí)間閱讀,回復(fù)【視頻】【書籍】領(lǐng)取200G視頻資料和30本PDF書籍資料