詳解vue-router的導(dǎo)航鉤子(導(dǎo)航守衛(wèi))
在做vue項(xiàng)目的時(shí)候,要求用戶在頁(yè)面訪問前先登錄,或在離開頁(yè)面前發(fā)出提醒。vue官方提供的路由管理器 vue-router 提供的導(dǎo)航鉤子,通過跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航。以下總結(jié)了路由鉤子函數(shù)的使用方法和一些使用場(chǎng)景。
一、全局守衛(wèi)
router.beforeEach 路由改變前的鉤子
const router = new VueRouter({ ... })
router.beforeEach((to, from, next) => {
... ...
})
其中:
- to:將要訪問的路徑
- from:代表從哪個(gè)路徑跳轉(zhuǎn)來的
- next:是一個(gè)函數(shù),表示放行。有如下幾種調(diào)用方式
- next():如果一起正常,則調(diào)用該方法進(jìn)入下一個(gè)鉤子;
- next(false):中斷當(dāng)前導(dǎo)航,即路由地址不發(fā)生變化;
- next('/xxx') 或 next({path: '/xxx'}):強(qiáng)制跳轉(zhuǎn)到指定路徑;
- next(error):如果傳入的是一個(gè)Error實(shí)例,則導(dǎo)航會(huì)被中斷且該錯(cuò)誤會(huì)被傳遞給 router.onError() 注冊(cè)過的回調(diào)。
使用:
使用該函數(shù),一定要調(diào)用 next(),否則鉤子函數(shù)不能 resolve;
該方法比較常用于:驗(yàn)證用戶訪問權(quán)限。
比如:一個(gè)系統(tǒng)需要先驗(yàn)證用戶是否登錄,如果登錄了就可以訪問,否則直接跳轉(zhuǎn)到登錄頁(yè)面。具體實(shí)現(xiàn)如下:
import Vue from 'vue'
import VueRouter from 'vue-router'
import { getToken } from '@Utils/session.utils' // 登錄用戶的token
import Login from '../pages/Login.vue' //引入登錄頁(yè)
const Home = () => import('../pages/Home.vue') //引入首頁(yè)
Vue.use(VueRouter) // 全局注入router
// 配置路由參數(shù)
const routes = [
{ path: '/login', name: 'login', component: Login },
{ path: '/home', name: 'home', component: Home }
]
const router = new VueRouter({
routes
})
// 全局掛載路由導(dǎo)航守衛(wèi):驗(yàn)證用戶是否登錄
router.beforeEach((to, from, next) => {
if (to.name !== 'login' && !getToken()) next('/login') // 如果用戶不是訪問登錄頁(yè)且沒有登錄,則強(qiáng)制跳轉(zhuǎn)到登錄頁(yè)
else next()
})
export default router
router.beforeResolve 在導(dǎo)航被確認(rèn)之前,同時(shí)在所有組件內(nèi)守衛(wèi)和異步路由組件被解析之后,該鉤子函數(shù)就被調(diào)用。
該方法我在項(xiàng)目中暫時(shí)還未使用到,具體使用場(chǎng)景歡迎大家補(bǔ)充 :)
router.afterEach 路由改變后的鉤子
router.afterEach((to, from) => {
... ...
})
該方法同全局前置守衛(wèi) router.beforeEach 不同的是少了 next() 函數(shù),也不會(huì)改變導(dǎo)航本身。
使用場(chǎng)景:
路由切換,將頁(yè)面的滾動(dòng)位置返回到頂部。
例如:一個(gè)頁(yè)面比較長(zhǎng),當(dāng)滾動(dòng)到某個(gè)位置后切換路由,這時(shí)跳轉(zhuǎn)的頁(yè)面滾動(dòng)條位置默認(rèn)是前一個(gè)頁(yè)面離開時(shí)停留的位置,可以通過該鉤子函數(shù)將滾動(dòng)條位置重置。
// 切換路由,頁(yè)面返回到頂部
router.afterEach((to, from) => {
window.scrollTo(0, 0)
})
二、路由獨(dú)享的守衛(wèi)
beforeEnter 對(duì)某個(gè)路由的單獨(dú)守衛(wèi),在路由配置上直接定義
const routes = [
{ path: '/login', name: 'login', component: Login },
{
path: '/home',
name: 'home',
component: Home,
beforeEnter: (to, from, next) => {
... ...
}
}
]
const router = new VueRouter({
routes
})
使用:
該方法的參數(shù)使用同全局前置守衛(wèi) router.beforeEach 是一樣的;
例如:根據(jù)登錄用戶的不同角色,展示不同的模塊;或者給指定路由組件單獨(dú)添加動(dòng)畫。
import Vue from 'vue'
import VueRouter from 'vue-router'
import { getUserRole } from '@Utils/session.utils' // 登錄用戶的角色
const UserCenter = () => import('../pages/UserCenter.vue')
const routes = [
... ...
{
path: '/usercenter',
name: 'usercenter',
component: UserCenter,
beforeEnter: (to, from, next) => {
if(getUserRole() === 'admin') next('/admincenter')
else next()
}
}
]
三、組件內(nèi)的守衛(wèi)
beforeRouteEnter(to, from, next) 在進(jìn)入當(dāng)前組件對(duì)應(yīng)的路由前調(diào)用
export default {
data() { ... },
beforeRouteEnter(to, from, next) {
... ...
}
}
注意:
該函數(shù)內(nèi)不能訪問當(dāng)前組件實(shí)例 this,因?yàn)楹瘮?shù)在對(duì)應(yīng)路由被 comfirm 前調(diào)用,此時(shí)將要渲染的組件實(shí)例還沒被創(chuàng)建;
可以通過給 next 傳遞一個(gè)回調(diào)來訪問組件實(shí)例,即把組件實(shí)例 vm 作為回調(diào)方法的參數(shù);該回調(diào)的執(zhí)行在 mounted 后面;
beforeRouteEnter (to, from, next) {
next(vm => {
// 通過 vm 來訪問組件實(shí)例
})
}
beforeRouteEnter 是支持給 next 傳遞回調(diào)的唯一守衛(wèi)。
使用場(chǎng)景:
例如:從一個(gè)列表頁(yè)進(jìn)入到詳情頁(yè),然后再返回到列表頁(yè),要求保留離開列表頁(yè)之前訪問的數(shù)據(jù)及滾動(dòng)位置,從其他頁(yè)面重新進(jìn)入列表頁(yè),獲取最新的數(shù)據(jù)。具體實(shí)現(xiàn)請(qǐng)點(diǎn)這里
beforeRouteUpdate(to, from, next) 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用
beforeRouteUpdate (to, from, next) {
... ...
}
注:
該函數(shù)內(nèi)可以訪問當(dāng)前組件實(shí)例 this
例如:在一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 /detail/:id,在 /detail/aaa 和 /detail/bbb 之間跳轉(zhuǎn)的時(shí)候,因?yàn)閮蓚€(gè)路由渲染的是同個(gè) Detail 組件,因此原來的組件實(shí)例會(huì)被復(fù)用(比起銷毀再創(chuàng)建,復(fù)用則會(huì)更加高效),在這種情況下這個(gè)鉤子會(huì)被調(diào)用,而組件的生命周期鉤子不會(huì)再被調(diào)用。
beforeRouteLeave(to, from, next) 在離開當(dāng)前組件對(duì)應(yīng)的路由前調(diào)用
beforeRouteLeave (to, from, next) {
... ...
}
注:
- 該函數(shù)內(nèi)可以訪問當(dāng)前組件實(shí)例 this;
- 比如:用戶在當(dāng)前頁(yè)面有還未保存的內(nèi)容時(shí)突然離開,阻止頁(yè)面跳轉(zhuǎn)并給出提示,或者在用戶離開時(shí)清除或存儲(chǔ)一些信息等。
四、完整的導(dǎo)航解析流程
- 導(dǎo)航被觸發(fā);
- 在失活的組件里調(diào)用 beforeRouteLeave 守衛(wèi);
- 調(diào)用全局的 beforeEach 守衛(wèi);
- 在重用的組件里調(diào)用 beforeRouteUpdate 守衛(wèi) (2.2+);
- 在路由配置里調(diào)用 beforeEnter;
- 解析異步路由組件;
- 在被激活的組件里調(diào)用 beforeRouteEnter;
- 調(diào)用全局的 beforeResolve 守衛(wèi) (2.5+);
- 導(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ù)傳入。
其實(shí)常用的也就那么幾個(gè),理解了其用法,路由導(dǎo)航的解析流程也就明了了。
五、附:使用 watch 監(jiān)測(cè)路由變化
除了使用鉤子函數(shù)外,我們也可以使用 watch 來監(jiān)聽 $route 對(duì)象,然后根據(jù)路由參數(shù)的變化來進(jìn)行響應(yīng)。
<template>
<div id=``"app"``>
<keep-alive>
<router-view/>
</keep-alive>
</div>
</template>
<script>
export default {
name: 'App',
watch: {
'$route' (to, from) {
// 對(duì)路由變化作出響應(yīng)...
}
}
}
</script>
到此這篇關(guān)于詳解vue-router的導(dǎo)航鉤子(導(dǎo)航守衛(wèi))的文章就介紹到這了,更多相關(guān)vue-router 導(dǎo)航鉤子內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue-cli?npm如何解決vue項(xiàng)目中缺失core-js的問題
這篇文章主要介紹了vue-cli?npm如何解決vue項(xiàng)目中缺失core-js的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08
vue3監(jiān)聽resize窗口事件(離開頁(yè)面要銷毀窗口事件)
這篇文章主要給大家介紹了關(guān)于vue3監(jiān)聽resize窗口事件(離開頁(yè)面要銷毀窗口事件)的相關(guān)資料,vue是單頁(yè)面應(yīng)用,路由切換后,定時(shí)器并不會(huì)自動(dòng)關(guān)閉,需要手動(dòng)清除,當(dāng)頁(yè)面被銷毀時(shí),清除定時(shí)器即可,需要的朋友可以參考下2023-11-11
vue項(xiàng)目中使用require.context引入組件
本文主要介紹了vue項(xiàng)目中使用require.context引入組件,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-08-08
詳解IOS微信上Vue單頁(yè)面應(yīng)用JSSDK簽名失敗解決方案
這篇文章主要介紹了詳解IOS微信上Vue單頁(yè)面應(yīng)用JSSDK簽名失敗解決方案,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2018-11-11
詳解如何制作并發(fā)布一個(gè)vue的組件的npm包
這篇文章主要介紹了詳解如何制作并發(fā)布一個(gè)vue的組件的npm包,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2018-11-11
nuxt框架中對(duì)vuex進(jìn)行模塊化設(shè)置的實(shí)現(xiàn)方法
這篇文章主要介紹了nuxt框架中對(duì)vuex進(jìn)行模塊化設(shè)置的實(shí)現(xiàn)方法,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-09-09
利用vue開發(fā)一個(gè)所謂的數(shù)獨(dú)方法實(shí)例
數(shù)獨(dú)是源自18世紀(jì)瑞士的一種數(shù)學(xué)游戲,是一種運(yùn)用紙、筆進(jìn)行演算的邏輯游戲。下面這篇文章主要給大家介紹了關(guān)于利用vue開發(fā)一個(gè)所謂的數(shù)獨(dú)的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考下。2017-12-12

