什麼是導航守衛
導航 指的是路由的改變。路由路徑是能任意輸入的,當我們需要判斷權限或登錄狀態來決定使用者使否能訪問路由時,就會用到 導航守衛(Navigation Guards),在路由發生變化時,做出相對應的處理。
簡單來說,就是在路由改變的過程中,會有一些函式鉤子可以讓我們用來處理一些事情。
完整的導航解析流程
先來看官方提供的導航解析流程:
- 導航被觸發。
- 在失活的元件裡呼叫
beforeRouteLeave守衛。 - 呼叫全域的
beforeEach守衛。 - 在重用的元件裡呼叫
beforeRouteUpdate守衛(2.2+)。 - 在路由配置裡呼叫
beforeEnter。 - 解析非同步路由元件。
- 在被激活的元件裡呼叫
beforeRouteEnter。 - 呼叫全域的
beforeResolve守衛(2.5+)。 - 導航被確認。
- 呼叫全域的
afterEach鉤子。 - 觸發 DOM 更新。
- 呼叫
beforeRouteEnter守衛中傳給next的回呼函式,創建好的元件實例會作為回呼函式的參數傳入。
導航守衛可以分成三種類型:
- 全域守衛
- 路由獨享守衛
- 元件內守衛
全域守衛
全域守衛會監測所有路由,按順序分為:
beforeEachbeforeResolveafterEach
1. 前置守衛
全域前置守衛會在跳轉前觸發,常用於登入驗證。
使用 router 物件的 beforeEach 方法註冊:
|
|
回呼函式接收的三個參數分別為:
to:即將要進入的目標路由物件。from:當前導航正要離開的路由物件。next:為一個函式,用來交出控制權或者中斷導航。
next 函式會根據傳入的參數而有不同的行為:
next():不傳入參數,會進入下一個守衛。如果全部鉤子都執行完,導航狀態就是 confirmed(確認的)。next(false):中斷當前導航。next('/')或next({ path: '/' }):跳轉至指定路由。next(error):如果傳入一個 Error 實體,導航會被終止且該錯誤會被傳遞給router.onError()。
:::warning
next 函式一定要呼叫,因為守衛式非同步解析執行,此時導航在所有守衛 resolve 完之前一直處於 等待中。但要注意,只能呼叫一次。
:::
2. 解析守衛
在 2.5.0 之後的版本,可以用 router.beforeResolve 註冊一個解析守衛
|
|
用法基本上與 beforeEach 相同,區別在於被呼叫的時間點:一樣是在跳轉前觸發,但會在 beforeEnter 呼叫之後,也就是 所有元件內守衛和非同步路由元件被解析之後 才呼叫。
3. 後置鉤子
afterEach 會在導航被確認後觸發,所以稱為 後置鉤子 而不是守衛。
|
|
它沒有 next 參數可用,因此不會改變導航本身。
路由獨享的守衛
如果你不想全域設置守衛,可以單獨在指定路由上設置守衛。
定義 beforeEnter 守衛:
|
|
參數與 beforeEach 相同。
元件內的守衛
在元件內也可直接定義以下路由導航守衛:
beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave
|
|
1. beforeRouteEnter
beforeRouteEnter 守衛內 不能 使用 this 獲取元件實體,因為它是在導航 confirm(確認)前被呼叫,新元件還尚未建立。
不過,我們可以透過傳遞一個回呼函式給 next 來訪問元件實體:
|
|
:::warning
beforeRouteEnter 是唯一支持 next 傳遞回呼函式的守衛。對於 beforeRouteUpdate 和 beforeRouteLeave 來說,已經透過 this 取得元件實體,所以沒必要。
:::
2. beforeRouteUpdate
beforeRouteUpdate 會在當前路由改變,但是該元件被覆用時呼叫。
舉例來說,對於一個帶有動態參數的路徑 /foo/:id,在 /foo/1 和 /foo/2 之間跳轉的時候,由於會渲染同樣的 Foo 元件,因此元件實體會被覆用。這個情況下的變化,就會觸發 Foo 元件的 beforeRouteUpdate。
通常用於父路由監聽子路由的變化。
3. beforeRouteLeave
beforeRouteLeave 會在導航離開該元件的對應路由時呼叫。
通常用於以下情況:假設當前路由為一個修改頁面,當使用者還未保存就突然離開,我們可以透過 next(false) 來取消。
|
|