導航守衛這個名字聽起來略微有點中二(手動滑稽)
迴歸正題,導航守衛大體上分爲以下三類:
1.全局守衛鉤子
2.獨享守衛鉤子
3.路由組件守衛鉤子
下面詳細說明以上三種守衛鉤子包含的方法及調用時序
1.全局守衛鉤子
全局守衛顧名思義是在路由全局執行,即在路由切換時無差別的執行鉤子(如果聲明的話)
全局守衛鉤子函數有三種
const router = new VueRouter({...});
//全局前置守衛
router.breforeEach((to, from, next) => {
//do something
})
//全局解析守衛
router.beforeResolve((to, from, next) => {
//do something
})
//全局後置守衛
router.afterEach((to, from) => {
//do something
})
to:route 即將進入的路由,to即路由對象,可訪問to.name、to.path...具體參照我的另外一篇路由對象屬性
from: route 即將離開的路由,即當前路由同樣是路由對象
next:function 這個是必須要調用的,如果沒有調用該方法那麼接下來所有的鉤子都不會被正常調用(頁面不會渲染等),next()接受參數,根據參數的不同執行結果也不同
參數 | 說明 |
next() | 直接執行下一個鉤子,如果執行完了導航狀態爲comfirmed |
next(false) | 中斷當前導航,回到from的位置 |
next('/hello') 或 next({path: '/hello'}) next({name: 'hello'})以及可以設置router.push裏的參數等 | 路由到任意地址,可以攜帶參數等 |
next(error) | 會回調到router.onError(callback),如果註冊過該回調的話 |
2.獨享守衛鉤子
獨享後衛鉤子是定義在單獨的某一個路由裏的,因此是此路由單獨觸發定義的鉤子與其他路由無關
const router = new VueRouter({
routes: [{
path: '/foo',
component: Foo,
beforeEnter: (to, from, next) => {
// do something
},
beforeLeave: (to, from, next) => {
//do something
}
}]
})
這裏的參數與全局前置守衛鉤子的參數使用相同
3.路由組件守衛鉤子
請注意這裏的路由組件四個字,區別於組件
即路由組件爲在vue-router裏註冊的組件叫路由組件,而不存在vue-router裏的組件(通俗例子就是如:一些可複用組件、彈窗組件、回到頂部組件等等)
這些鉤子只能在路由組件裏聲明可用,在非路由組件裏聲明不會報錯,但是也沒有任何效果
<template>
<span>1111</span>
</template>
<script>
export default {
name: 'Hello',
props: ['name'],
mounted () {
//...
},
beforeRouteEnter (to, from, next) {
//這裏!不!能!直接訪問該組件的this實例
//此時路由導航還未被確認,組件還未實例化
//但是可通過在next的回調中訪問,且只有該鉤子支持接受回調參數
next(vm => {})
},
beforeRouteUpdate (to, from, next) {
//當前基礎路由沒有變化,但參數發生變化時使用
//如動態路由 /hello/:name,在/hello/smith 與 /hello/grace之間轉跳
//由於使用的是同一hello組件,只是數據變化,因此該組件會被複用
//可以訪問組件實例this,此時已是完整的組件
},
beforeRouteLeave (to, from, next) {
//離開該組件是使用
}
}
</script>
以上都必須使用next(),否則會導致組件無法正常進行渲染
4.完整的導航流程
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 的回調函數。
以上全部參考vue-router官方文檔