vue路由鉤子函數(shù)有2種,分別為:1、全局守衛(wèi)(全局鉤子函數(shù)),指的是“index.js”中的router對(duì)象;2、路由守衛(wèi)(針對(duì)單個(gè)路由鉤子函數(shù));3、組件守衛(wèi)(組件級(jí)鉤子函數(shù)),是定義在路由組件內(nèi)部的守衛(wèi)。
本教程操作環(huán)境:windows7系統(tǒng)、vue2.9.6版,DELL G3電腦。
vue-router
的 鉤子函數(shù) ,其實(shí)說(shuō)的就是 導(dǎo)航守衛(wèi) 。
引用官網(wǎng)的話
“導(dǎo)航” 表示路由正在發(fā)生改變。
vue-router
提供的導(dǎo)航守衛(wèi)主要用來(lái)通過(guò) 跳轉(zhuǎn) 或 取消 的方式 守衛(wèi)導(dǎo)航 。有多種機(jī)會(huì)植入路由導(dǎo)航過(guò)程中:全局的, 單個(gè)路由獨(dú)享的, 或者組件級(jí)的。
也就是:全局守衛(wèi)(全局鉤子函數(shù))、路由守衛(wèi)(針對(duì)單個(gè)路由鉤子函數(shù))、組件守衛(wèi)(組件級(jí)鉤子函數(shù))。
代碼演示環(huán)境搭建
先簡(jiǎn)單搭建一下環(huán)境
index.js
import { createRouter, createWebHashHistory } from 'vue-router'; const router = createRouter({ history: createWebHashHistory(), routes: [ { path: '/a', component: () => import('../components/A.vue'), }, { path: '/b', component: () => import('../components/B.vue'), }, { path: '/c', component: () => import('../components/C.vue'), }, ], }); export default router;
main.js
// index.js import router from "./router"; createApp(App).use(router).mount("#app");
頁(yè)面A
<template> <div> <h1>我是頁(yè)面A啊</h1> <comp></comp> </div> </template>
頁(yè)面B
<template> <div> <h1>我是頁(yè)面B啊</h1> <comp></comp> </div> </template>
頁(yè)面C
<template> <div> <h1>我是頁(yè)面C啊</h1> <comp></comp> </div> </template>
通用組件
<template> <div>我是公用組件啊</div> </template>
當(dāng)前頁(yè)面是這樣的,有點(diǎn)丑,湊活看吧,咱也不是來(lái)學(xué)習(xí) css
的
全局守衛(wèi)
顧名思義,是要定義在全局的,也就是我們 index.js
中的 router
對(duì)象。
beforeEach
全局前置守衛(wèi),在路由跳轉(zhuǎn)前觸發(fā),它在 每次導(dǎo)航 時(shí)都會(huì)觸發(fā)。
通過(guò) router.beforeEach
注冊(cè)一個(gè)全局前置守衛(wèi)。
參數(shù)
beforeEach
全局前置守衛(wèi)接收三個(gè)參數(shù)
- to: Route: 即將要進(jìn)入的目標(biāo)路由對(duì)象
- from: Route: 當(dāng)前導(dǎo)航正要離開的路由對(duì)象
- next: Function: 一定要調(diào)用該方法不然會(huì)阻塞路由。
注意: next
參數(shù)可以不添加,但是一旦添加,則必須調(diào)用一次,否則路由跳轉(zhuǎn)等會(huì)停止。
next()
方法的幾種情況
- next(): 進(jìn)行管道中的下一個(gè)鉤子。
- next(false): 中斷當(dāng)前的導(dǎo)航?;氐?
from
路由對(duì)應(yīng)的地址。 - next(’/’) 或者 next({ path: ‘/’ }): 跳轉(zhuǎn)到一個(gè)不同的地址,可傳遞的參數(shù)與
router.push
中選項(xiàng)一致。 - next(error): 導(dǎo)航終止,且該錯(cuò)誤會(huì)被傳遞給
router.onError()
注冊(cè)過(guò)的回調(diào)。
我們把前兩個(gè)參數(shù)打印出來(lái)看一下,里面包含路徑,參數(shù),元信息等內(nèi)容。
返回值
- false:取消當(dāng)前的導(dǎo)航。
- null,undefined,true或者直接return:調(diào)用下一個(gè)導(dǎo)航守衛(wèi)。
定義多個(gè)守衛(wèi)
全局前置守衛(wèi)可以定義多個(gè),根據(jù)創(chuàng)建順序調(diào)用。在所有守衛(wèi)完成之前導(dǎo)航一直處于等待中。
下面這個(gè)例子中我們就定義了兩個(gè) beforeEach
全局前置守衛(wèi)??梢钥吹?,只有在兩秒以后分別打印出兩條日志后才進(jìn)行頁(yè)面的跳轉(zhuǎn)。
除了 beforeEach
全局前置守衛(wèi)之外,其他的全局守衛(wèi)都可以定義多個(gè),并且在所有守衛(wèi)完成之前導(dǎo)航一直處于等待中,其他的鉤子函數(shù)就不進(jìn)行演示了。
beforeResolve
全局解析守衛(wèi),在路由跳轉(zhuǎn)前,所有 組件內(nèi)守衛(wèi) 和 異步路由組件 被解析之后觸發(fā),它同樣在 每次導(dǎo)航 時(shí)都會(huì)觸發(fā)。
通過(guò) router.beforeResolve
注冊(cè)一個(gè)全局解析守衛(wèi)。
router.beforeResolve((to, from, next) => { next(); })
回調(diào)參數(shù),返回值和 beforeEach
一樣。也可以定義多個(gè)全局解析守衛(wèi)。
afterEach
全局后置鉤子,它發(fā)生在路由跳轉(zhuǎn)完成后,beforeEach
和 beforeResolve
之后,beforeRouteEnter
(組件內(nèi)守衛(wèi))之前。它同樣在 每次導(dǎo)航 時(shí)都會(huì)觸發(fā)。
通過(guò) router.afterEach
注冊(cè)一個(gè)全局后置鉤子。
這個(gè)鉤子的兩個(gè)參數(shù)和 beforeEach
中的 to
和 from
一樣。然而和其它全局鉤子不同的是,這些鉤子不會(huì)接受 next
函數(shù),也不會(huì)改變導(dǎo)航本身。
路由守衛(wèi)
顧名思義,就是跟路由相關(guān)的鉤子,我們的路由守衛(wèi)只有一個(gè),就是 beforeEnter
。
beforeEnter
需要在路由配置上定義 beforeEnter
守衛(wèi),此守衛(wèi)只在進(jìn)入路由時(shí)觸發(fā),在 beforeEach
之后緊隨執(zhí)行,不會(huì)在 params
、query
或 hash
改變時(shí)觸發(fā)。
beforeEnter
路由守衛(wèi)的參數(shù)是 to
、from
、next
,同 beforeEach
一樣。
組件守衛(wèi)
顧名思義,是定義在路由組件內(nèi)部的守衛(wèi)。
beforeRouteEnter
路由進(jìn)入組件之前調(diào)用,該鉤子在全局守衛(wèi) beforeEach
和路由守衛(wèi) beforeEnter
之后,全局 beforeResolve
和全局 afterEach
之前調(diào)用。
參數(shù)包括 to
,from
,next
。
該守衛(wèi)內(nèi)訪問(wèn)不到組件的實(shí)例,也就是 this
為 undefined
,也就是他在 beforeCreate
生命周期前觸發(fā)。
beforeRouteUpdate
對(duì)于 beforeRouteUpdate
來(lái)說(shuō),this
已經(jīng)可用了,所以給 next
傳遞回調(diào)就沒有必要了。
beforeRouteLeave
對(duì)于 beforeRouteLeave
來(lái)說(shuō),this
已經(jīng)可用了,所以給 next
傳遞回調(diào)就沒有必要了。
總結(jié)
完整的導(dǎo)航解析流程
- 導(dǎo)航被觸發(fā)。
- 在失活的組件里調(diào)用
beforeRouteLeave
守衛(wèi)。- 調(diào)用全局的
beforeEach
守衛(wèi)。- 在重用的組件里調(diào)用
beforeRouteUpdate
守衛(wèi)。- 在路由配置里調(diào)用
beforeEnter
。- 解析異步路由組件。
- 在被激活的組件里調(diào)用
beforeRouteEnter
。- 調(diào)用全局的
beforeResolve
守衛(wèi)。- 導(dǎo)航被確認(rèn)。
- 調(diào)用全局的
afterEach
鉤子。- 觸發(fā)
DOM
更新。- 調(diào)用
beforeRouteEnter
守衛(wèi)中傳給next
的回調(diào)函數(shù),創(chuàng)建好的組件實(shí)例會(huì)作為回調(diào)函數(shù)的參數(shù)傳入。
上面是官方給出的答案,現(xiàn)在我們用流程圖來(lái)直觀的展示一下。