路由守衛其實就是導航守衛,我們可以通過路由守衛來判斷用戶是否登錄,該頁面用戶是否有瀏覽權限,用戶信息是否存在等等。
路由守衛分爲三種:全局守衛、路由獨享的守衛、組件內的守衛。
這裏有一個例子,可以很好的幫助我們來理解。
所謂的路由守衛可以簡單的理解爲一座房子的門口的保安,想要進入這個房子就必須通過保安的檢查,要告訴路由守衛你從哪裏來?總不能隨便陌生人就給放進去?要到哪裏去?然後保安再告訴你下一步該怎麼做?如果你的確是這個房子主人允許進入的人,那就讓你進入,否則就要打電話給房子主人,跟房主商量(登錄註冊),給你權限。
全局路由守衛
所謂全局路由守衛,就是小區大門,整個小區就這一個大門,你想要進入其中任何一個房子,都需要經過這個大門的檢查
全局路由守衛分爲全局前置守衛,全局後置守衛
可以使用router.beforeEach註冊一個全局前置守衛
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
// ...
})
當一個導航觸發時,全局前置守衛按照創建順序調用。守衛是異步解析執行,此時導航在所有守衛resolve完之前一直處於等待中。
每個守衛方法接收三個參數:
- to:Route:即將要進入的目標 路由對象。
- from:Route:當前導航正要離開的路由
- next:Function:一定要調用這個方法來resolve這個鉤子。
- next():進行管道中的下一個鉤子。如果全部鉤子執行完了,則導航的狀態就是 confirmed (確認的)。
- next(false): 中斷當前的導航。如果瀏覽器的 URL 改變了 (可能是用戶手動或者瀏覽器後退按鈕),那麼 URL 地址會重置到 from 路由對應的地址。
- next('/') 或者 next({ path: '/' }): 跳轉到一個不同的地址。當前的導航被中斷,然後進行一個新的導航。你可以向 next 傳遞任意位置對象,且允許設置諸如 replace: true、name: 'home' 之類的選項以及任何用在 router-link 的 to prop 或 router.push 中的選項。
- next(error): (2.4.0+) 如果傳入 next 的參數是一個 Error 實例,則導航會被終止且該錯誤會被傳遞給 router.onError() 註冊過的回調。
確保要調用next方法,否則鉤子就不會被resolved
路由獨享的守衛
可以在路由配置上直接定義beforeEnter守衛:
const router = new VueRouter({
routes: [
{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// ...
}
}
]
})
組件內的守衛
const Foo = {
template: `...`,
beforeRouteEnter (to, from, next) {
// 在渲染該組件的對應路由被 confirm 前調用
// 不!能!獲取組件實例 `this`
// 因爲當守衛執行前,組件實例還沒被創建
},
beforeRouteUpdate (to, from, next) {
// 在當前路由改變,但是該組件被複用時調用
// 舉例來說,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,
// 由於會渲染同樣的 Foo 組件,因此組件實例會被複用。而這個鉤子就會在這個情況下被調用。
// 可以訪問組件實例 `this`
},
beforeRouteLeave (to, from, next) {
// 導航離開該組件的對應路由時調用
// 可以訪問組件實例 `this`
}
}
完整的導航解析流程
1、導航被觸發。
2、在失活的組件裏調用離開守衛。
3、調用全局的 beforeEach 守衛。
4、在重用的組件裏調用 beforeRouteUpdate 守衛 (2.2+)。
5、在路由配置裏調用 beforeEnter。
6、解析異步路由組件。
7、在被激活的組件裏調用 beforeRouteEnter。
8、調用全局的 beforeResolve 守衛 (2.5+)。
9、導航被確認。
10、調用全局的 afterEach 鉤子。
11、觸發 DOM 更新。
12、用創建好的實例調用 beforeRouteEnter 守衛中傳給 next 的回調函數。
官網鏈接: