一文詳解vue-router中的導(dǎo)航守衛(wèi)
導(dǎo)航守衛(wèi)是什么
按照官方文檔說(shuō)明,vue-router
提供的導(dǎo)航守衛(wèi)主要用來(lái)通過(guò)跳轉(zhuǎn)或取消的方式守衛(wèi)導(dǎo)航。這里有很多方式植入路由導(dǎo)航中:全局的,單個(gè)路由獨(dú)享的,或者組件級(jí)的。
在 vue-router
中,導(dǎo)航守衛(wèi)是一種非常重要的功能,它允許你在路由導(dǎo)航過(guò)程中添加邏輯驗(yàn)證和處理,比如判斷用戶(hù)是否登錄,如果沒(méi)有登錄就跳轉(zhuǎn)到登錄頁(yè)面,如果已經(jīng)登錄就跳轉(zhuǎn)到首頁(yè)。
導(dǎo)航守衛(wèi)的分類(lèi)
在 Vue Router
中,有三種類(lèi)型的導(dǎo)航守衛(wèi)方法可以使用:
全局守衛(wèi):
beforeEach
和afterEach
。獨(dú)享路由守衛(wèi):
beforeEnter
。組件內(nèi)路由守衛(wèi):
beforeRouteEnter
、beforeRouteUpdate
和beforeRouteLeave
。
全局守衛(wèi)
全局守衛(wèi)就是在路由跳轉(zhuǎn)時(shí),對(duì)整個(gè)應(yīng)用內(nèi)的所有路由進(jìn)行攔截,然后進(jìn)行一些操作。
全局守衛(wèi)分為全局前置守衛(wèi)
和全局后置守衛(wèi)
。
全局前置守衛(wèi)
就是在路由跳轉(zhuǎn)之前進(jìn)行攔截,全局后置守衛(wèi)
就是在路由跳轉(zhuǎn)之后進(jìn)行攔截。
全局前置守衛(wèi)的使用方法如下:
router.beforeEach((to, from, next) => { // ... })
全局后置守衛(wèi)的使用方法如下:
router.afterEach((to, from) => { // ... })
路由獨(dú)享守衛(wèi)
路由獨(dú)享守衛(wèi)就是在路由跳轉(zhuǎn)時(shí),對(duì)應(yīng)用內(nèi)的某個(gè)特定的路由進(jìn)行攔截,然后進(jìn)行一些操作。
路由獨(dú)享守衛(wèi)的使用方法如下:
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { // ... } } ] })
組件內(nèi)守衛(wèi)
組件內(nèi)守衛(wèi)就是在組件內(nèi)部定義的特殊守衛(wèi)方法,用于處理組件級(jí)別的路由導(dǎo)航。常見(jiàn)的組件內(nèi)守衛(wèi)包括:
beforeRouteEnter
: 在路由進(jìn)入組件之前被調(diào)用,可以訪問(wèn)不到組件實(shí)例(this),但可以通過(guò)回調(diào)函數(shù)獲取組件實(shí)例。beforeRouteUpdate
: 在當(dāng)前路由被復(fù)用時(shí)調(diào)用,例如同一個(gè)組件在不同參數(shù)下進(jìn)行切換時(shí)。beforeRouteLeave
: 在離開(kāi)當(dāng)前路由之前調(diào)用,可以詢(xún)問(wèn)用戶(hù)是否保存未保存的數(shù)據(jù)或執(zhí)行其他清理操作。
const UserDetails = { template: `...`, beforeRouteEnter(to, from) { // 在渲染該組件的對(duì)應(yīng)路由被驗(yàn)證前調(diào)用 // 不能獲取組件實(shí)例 `this` ! // 因?yàn)楫?dāng)守衛(wèi)執(zhí)行時(shí),組件實(shí)例還沒(méi)被創(chuàng)建! }, beforeRouteUpdate(to, from) { // 在當(dāng)前路由改變,但是該組件被復(fù)用時(shí)調(diào)用 // 舉例來(lái)說(shuō),對(duì)于一個(gè)帶有動(dòng)態(tài)參數(shù)的路徑 `/users/:id`,在 `/users/1` 和 `/users/2` 之間跳轉(zhuǎn)的時(shí)候, // 由于會(huì)渲染同樣的 `UserDetails` 組件,因此組件實(shí)例會(huì)被復(fù)用。而這個(gè)鉤子就會(huì)在這個(gè)情況下被調(diào)用。 // 因?yàn)樵谶@種情況發(fā)生的時(shí)候,組件已經(jīng)掛載好了,導(dǎo)航守衛(wèi)可以訪問(wèn)組件實(shí)例 `this` }, beforeRouteLeave(to, from) { // 在導(dǎo)航離開(kāi)渲染該組件的對(duì)應(yīng)路由時(shí)調(diào)用 // 與 `beforeRouteUpdate` 一樣,它可以訪問(wèn)組件實(shí)例 `this` }, }
導(dǎo)航守衛(wèi)的參數(shù)
導(dǎo)航守衛(wèi)的參數(shù)如下:
to
: 即將要進(jìn)入的目標(biāo)路由對(duì)象,包含了目標(biāo)路由的路徑、參數(shù)、查詢(xún)參數(shù)等信息,可以用來(lái)判斷要導(dǎo)航到哪個(gè)路由。from
: 當(dāng)前導(dǎo)航正要離開(kāi)的路由,包含了當(dāng)前路由的路徑、參數(shù)、查詢(xún)參數(shù)等信息,可以用來(lái)判斷當(dāng)前路由的狀態(tài)。next
方法:用于控制導(dǎo)航行為。它有以下幾種用法:next()
: 允許導(dǎo)航,繼續(xù)進(jìn)行下一步導(dǎo)航操作。next(false)
: 取消導(dǎo)航,終止當(dāng)前導(dǎo)航操作。next('/')
或next({ path: '/' })
: 重定向到指定的路徑。next(error)
: 導(dǎo)航出錯(cuò),可以傳遞一個(gè)錯(cuò)誤對(duì)象給 next 方法。
導(dǎo)航守衛(wèi)的執(zhí)行順序
導(dǎo)航守衛(wèi)的執(zhí)行順序如下:
全局前置守衛(wèi) -> 路由獨(dú)享守衛(wèi) -> 組件內(nèi)守衛(wèi) -> 全局后置守衛(wèi)
導(dǎo)航守衛(wèi)的使用場(chǎng)景
全局前置守衛(wèi)
- 判斷用戶(hù)是否登錄,如果沒(méi)有登錄就跳轉(zhuǎn)到登錄頁(yè)面,如果已經(jīng)登錄就跳轉(zhuǎn)到首頁(yè)。
router.beforeEach((to, from, next) => { if (to.path === '/login') { next() } else { const token = localStorage.getItem('token') if (!token) { next('/login') } else { next() } } })
全局后置守衛(wèi)
- 記錄用戶(hù)訪問(wèn)的頁(yè)面。
router.afterEach((to, from) => { localStorage.setItem('path', to.path) })
路由獨(dú)享守衛(wèi)
- 判斷用戶(hù)是否有權(quán)限訪問(wèn)某個(gè)頁(yè)面,如果沒(méi)有權(quán)限就跳轉(zhuǎn)到首頁(yè)。
const router = new VueRouter({ routes: [ { path: '/foo', component: Foo, beforeEnter: (to, from, next) => { const token = localStorage.getItem('token') if (!token) { next('/') } else { const role = localStorage.getItem('role') if (to.meta.role && to.meta.role.indexOf(role) === -1) { next('/') } else { next() } } } } ] })
組件內(nèi)守衛(wèi)
- 數(shù)據(jù)預(yù)加載:在進(jìn)入組件之前,需要先加載一些數(shù)據(jù)。可以使用
beforeRouteEnter
組件內(nèi)守衛(wèi)來(lái)調(diào)用接口獲取數(shù)據(jù),并在數(shù)據(jù)加載完成后再進(jìn)入組件。
const Foo = { beforeRouteEnter(to, from, next) { fetchData().then(data => { next(vm => { vm.data = data; // 將數(shù)據(jù)傳遞給組件實(shí)例 }); }); }, };
- 路由參數(shù)更新:當(dāng)同一個(gè)組件在不同參數(shù)下進(jìn)行切換時(shí),可能需要根據(jù)新的參數(shù)更新組件的數(shù)據(jù)或狀態(tài)??梢允褂?nbsp;
beforeRouteUpdate
組件內(nèi)守衛(wèi)來(lái)處理這種情況。
const Baz = { beforeRouteUpdate(to, from, next) { if (to.params.id !== from.params.id) { // 當(dāng)路由參數(shù) id 發(fā)生變化時(shí),重新請(qǐng)求數(shù)據(jù) this.fetchData(to.params.id); } next(); }, };
- 數(shù)據(jù)清理:在離開(kāi)當(dāng)前路由之前需要執(zhí)行一些清理操作,例如取消訂閱事件、重置組件狀態(tài)等??梢允褂?nbsp;
beforeRouteLeave
組件內(nèi)守衛(wèi)來(lái)處理這些操作。
const Bar = { beforeRouteLeave(to, from, next) { if (this.hasUnsavedChanges()) { if (confirm('是否保存修改的數(shù)據(jù)?')) { this.saveData(); // 保存修改的數(shù)據(jù) } } next(); };
- 頁(yè)面切換動(dòng)畫(huà):在切換頁(yè)面時(shí)添加過(guò)渡動(dòng)畫(huà)效果,以提升用戶(hù)體驗(yàn)??梢栽?nbsp;
beforeRouteEnter
和beforeRouteLeave
組件內(nèi)守衛(wèi)中設(shè)置過(guò)渡動(dòng)畫(huà)的相關(guān)邏輯。
const Qux = { beforeRouteEnter(to, from, next) { // 在進(jìn)入組件之前設(shè)置初始過(guò)渡狀態(tài) this.transitionName = 'slide-in'; next(); }, beforeRouteLeave(to, from, next) { // 在離開(kāi)組件之前設(shè)置過(guò)渡狀態(tài) this.transitionName = 'slide-out'; next(); }, };
到此這篇關(guān)于一文詳解vue-router中的導(dǎo)航守衛(wèi)的文章就介紹到這了,更多相關(guān)vue-router導(dǎo)航守衛(wèi)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue項(xiàng)目持久化存儲(chǔ)數(shù)據(jù)的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue項(xiàng)目持久化存儲(chǔ)數(shù)據(jù)的實(shí)現(xiàn)代碼,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-10-10vue虛擬滾動(dòng)/虛擬列表簡(jiǎn)單實(shí)現(xiàn)示例
本文主要介紹了vue虛擬滾動(dòng)/虛擬列表簡(jiǎn)單實(shí)現(xiàn)示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2025-01-01Vue3組合式函數(shù)Composable實(shí)戰(zhàn)ref和unref使用
這篇文章主要為大家介紹了Vue3組合式函數(shù)Composable實(shí)戰(zhàn)ref和unref使用詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-06-06