Vue-Router路由守衛(wèi)詳?shù)募?xì)用法教程
引言
在Vue.js應(yīng)用中,Vue-Router是一個(gè)非常重要的插件,它允許我們實(shí)現(xiàn)頁面間的導(dǎo)航。然而,僅僅實(shí)現(xiàn)導(dǎo)航是不夠的,我們還需要在導(dǎo)航的不同階段進(jìn)行各種操作,如用戶認(rèn)證、權(quán)限管理、數(shù)據(jù)預(yù)加載等。這時(shí),路由守衛(wèi)就派上了用場(chǎng)。本文將結(jié)合實(shí)際案例,詳細(xì)介紹Vue-Router路由守衛(wèi)的用法。
一、路由守衛(wèi)的基本概念
路由守衛(wèi)是Vue-Router提供的一種機(jī)制,用于在路由跳轉(zhuǎn)前或跳轉(zhuǎn)后執(zhí)行一些操作。它類似于Vue組件中的生命周期鉤子函數(shù),但它是針對(duì)路由的。通過路由守衛(wèi),我們可以在用戶訪問特定路由前或離開 特定路由后執(zhí)行一些邏輯,從而控制用戶訪問權(quán)限、加載數(shù)據(jù)或取消導(dǎo)航等操作。
Vue-Router中的路由守衛(wèi)主要分為三類:全局守衛(wèi)、路由獨(dú)享守衛(wèi)和組件內(nèi)守衛(wèi)。
- 全局守衛(wèi):在整個(gè)應(yīng)用的任何路由跳轉(zhuǎn)前或跳轉(zhuǎn)后執(zhí)行。全局守衛(wèi)適用于應(yīng)用級(jí)別的邏輯,如用戶登錄狀態(tài)檢查。
- 路由獨(dú)享守衛(wèi):在特定路由跳轉(zhuǎn)前或跳轉(zhuǎn)后執(zhí)行。路由獨(dú)享守衛(wèi)適用于特定路由的邏輯,如管理員權(quán)限檢查。
- 組件內(nèi)守衛(wèi):定義在組件內(nèi)部的守衛(wèi),它分為beforeRouteEnter、beforeRouteUpdate和beforeRouteLeave。組件內(nèi)守衛(wèi)適合與組件自身相關(guān)的邏輯,如數(shù)據(jù)預(yù)加載和頁面離開確認(rèn)。
二、全局守衛(wèi)
全局守衛(wèi)是在Vue Router實(shí)例上注冊(cè)的,可以對(duì)所有路由變化進(jìn)行監(jiān)聽。全局守衛(wèi)包括全局前置守衛(wèi)(beforeEach)、全局解析守衛(wèi)(beforeResolve)和全局后置守衛(wèi)(afterEach)。
- 全局前置守衛(wèi)(beforeEach)
全局前置守衛(wèi)在每次導(dǎo)航之前調(diào)用,常用于檢查用戶是否登錄以及用戶權(quán)限驗(yàn)證等。
示例代碼:
import Vue from 'vue';
import Router from 'vue-router';
import Home from '@/components/Home';
import About from '@/components/About';
import Login from '@/components/Login';
Vue.use(Router);
const router = new Router({
routes: [
{ path: '/', component: Home },
{ path: '/about', component: About, meta: { requiresAuth: true } },
{ path: '/login', component: Login }
]
});
// 假設(shè)我們有一個(gè)檢查用戶是否登錄的函數(shù)
function isUserLoggedIn() {
// 這里可以是一個(gè)實(shí)際的登錄檢查邏輯,比如查詢cookie或Vuex狀態(tài)
return false; // 這里我們假設(shè)用戶未登錄
}
// 全局前置守衛(wèi)
router.beforeEach((to, from, next) => {
// 檢查目標(biāo)路由是否需要認(rèn)證
if (to.meta.requiresAuth && !isUserLoggedIn()) {
// 如果需要認(rèn)證且用戶未登錄,則跳轉(zhuǎn)到登錄頁
next('/login');
} else {
// 否則允許訪問
next();
}
});
export default router;
在上面的示例中,我們定義了一個(gè)全局前置守衛(wèi),它會(huì)在每次路由跳轉(zhuǎn)前檢查目標(biāo)路由是否需要認(rèn)證(通過meta屬性中的requiresAuth標(biāo)識(shí))。如果需要認(rèn)證且用戶未登錄,則重定向到登錄頁。
- 全局解析守衛(wèi)(beforeResolve)
全局解析守衛(wèi)在導(dǎo)航被確認(rèn)前調(diào)用,常用于異步獲取數(shù)據(jù)后再渲染組件的場(chǎng)景。這個(gè)守衛(wèi)與全局前置守衛(wèi)類似,但它在導(dǎo)航被確認(rèn)之前被調(diào)用,這意味著它可以在導(dǎo)航被阻止之前解析數(shù)據(jù)。
示例代碼:
router.beforeResolve((to, from, next) => {
// 在這里進(jìn)行異步數(shù)據(jù)獲取操作
// 比如通過API請(qǐng)求獲取數(shù)據(jù)
console.log('導(dǎo)航即將被確認(rèn),可以進(jìn)行數(shù)據(jù)獲取操作');
next();
});
在上面的示例中,我們?cè)谌纸馕鍪匦l(wèi)中進(jìn)行了數(shù)據(jù)獲取操作。注意,這個(gè)守衛(wèi)不會(huì)中斷導(dǎo)航過程,它只是用于在導(dǎo)航確認(rèn)之前進(jìn)行數(shù)據(jù)獲取。
- 全局后置守衛(wèi)(afterEach)
全局后置守衛(wèi)在每次導(dǎo)航之后調(diào)用,常用于統(tǒng)計(jì)頁面PV、修改頁面title等操作。這個(gè)守衛(wèi)不接受next函數(shù),也不可以中斷導(dǎo)航。
示例代碼:
router.afterEach((to, from) => {
// 在這里進(jìn)行頁面title設(shè)置等操作
document.title = to.meta.title || '默認(rèn)標(biāo)題';
console.log('導(dǎo)航已完成');
});
在上面的示例中,我們?cè)谌趾笾檬匦l(wèi)中設(shè)置了頁面title,并打印了導(dǎo)航完成的消息。
三、路由獨(dú)享守衛(wèi)
路由獨(dú)享守衛(wèi)是在路由配置中直接定義的守衛(wèi),它只應(yīng)用于單個(gè)路由或一組路由。這種守衛(wèi)允許我們針對(duì)特定的路由實(shí)施一些邏輯,如驗(yàn)證用戶是否有權(quán)限訪問某個(gè)頁面。
示例代碼:
const routes = [
{
path: '/admin',
component: Admin,
meta: { requiresAuth: true, requiresAdmin: true },
beforeEnter: (to, from, next) => {
// 假設(shè)我們有一個(gè)檢查用戶是否登錄和是否具備管理員權(quán)限的函數(shù)
function isUserLoggedIn() { return false; } // 用戶未登錄
function isUserAdmin() { return true; } // 用戶是管理員(這里只是模擬)
// 檢查用戶是否登錄
if (to.meta.requiresAuth && !isUserLoggedIn()) {
// 如果需要認(rèn)證且用戶未登錄,則重定向到登錄頁
next('/login');
} else if (to.meta.requiresAdmin && !isUserAdmin()) {
// 如果需要管理員權(quán)限且用戶不是管理員,則重定向到無權(quán)限頁面
next('/403');
} else {
// 否則允許訪問
next();
}
}
}
];
const router = new Router({
routes
});
在上面的示例中,我們定義了一個(gè)路由獨(dú)享守衛(wèi),它會(huì)在進(jìn)入/admin路由前檢查用戶是否登錄和是否具備管理員權(quán)限。如果需要認(rèn)證且用戶未登錄,則重定向到登錄頁;如果需要管理員權(quán)限且用戶不是管理員,則重定向到無權(quán)限頁面。
四、組件內(nèi)守衛(wèi)
組件內(nèi)守衛(wèi)是在組件內(nèi)定義的守衛(wèi),它分為beforeRouteEnter、beforeRouteUpdate和beforeRouteLeave。
- beforeRouteEnter
在進(jìn)入路由前執(zhí)行,可以在這里進(jìn)行數(shù)據(jù)預(yù)加載等操作。由于組件實(shí)例在守衛(wèi)執(zhí)行時(shí)還未被創(chuàng)建,因此不能訪問this。可以通過將回調(diào)傳遞給next函數(shù)來訪問組件實(shí)例。
示例代碼:
export default {
name: 'MyComponent',
beforeRouteEnter(to, from, next) {
// 在進(jìn)入路由前執(zhí)行數(shù)據(jù)預(yù)加載等操作
console.log('準(zhǔn)備進(jìn)入MyComponent組件');
next(vm => {
// 訪問組件實(shí)例
vm.fetchData();
});
},
methods: {
fetchData() {
// 數(shù)據(jù)加載邏輯
console.log('加載數(shù)據(jù)');
}
}
};
在上面的示例中,我們?cè)赽eforeRouteEnter守衛(wèi)中進(jìn)行了數(shù)據(jù)預(yù)加載操作,并通過回調(diào)訪問了組件實(shí)例以調(diào)用數(shù)據(jù)加載方法。
- beforeRouteUpdate
在當(dāng)前路由改變時(shí)執(zhí)行,但組件實(shí)例被復(fù)用。這可以用于響應(yīng)路由參數(shù)的變化。
示例代碼:
export default {
name: 'MyComponent',
beforeRouteUpdate(to, from, next) {
// 在路由變化時(shí)執(zhí)行數(shù)據(jù)更新等操作
console.log('MyComponent組件的路由正在更新');
this.fetchData(); // 調(diào)用數(shù)據(jù)更新方法
next();
},
methods: {
fetchData(params) {
// 根據(jù)新的路由參數(shù)加載數(shù)據(jù)
console.log('根據(jù)新參數(shù)加載數(shù)據(jù)');
}
}
};
注意:在上面的示例中,我們假設(shè)fetchData方法可以接受參數(shù),但beforeRouteUpdate守衛(wèi)并沒有直接傳遞參數(shù)給fetchData方法。在實(shí)際應(yīng)用中,你可能需要根據(jù)路由參數(shù)的變化來動(dòng)態(tài)加載數(shù)據(jù),這時(shí)你可以在beforeRouteUpdate守衛(wèi)中獲取新的路由參數(shù)并傳遞給fetchData方法。
- beforeRouteLeave
在離開當(dāng)前路由前執(zhí)行,可以用于提示用戶是否確認(rèn)離開當(dāng)前頁面。
示例代碼:
export default {
name: 'MyComponent',
data() {
return {
hasUnsavedChanges: false // 用于標(biāo)識(shí)是否有未保存的更改
};
},
beforeRouteLeave(to, from, next) {
// 在離開當(dāng)前路由前執(zhí)行確認(rèn)操作
if (this.hasUnsavedChanges) {
// 提示用戶是否確認(rèn)離開
const answer = window.confirm('你有未保存的更改,確認(rèn)離開嗎?');
if (answer) {
next(); // 用戶確認(rèn)離開,允許導(dǎo)航
} else {
next(false); // 用戶取消離開,阻止導(dǎo)航
}
} else {
next(); // 沒有未保存的更改,允許導(dǎo)航
}
}
};
在上面的示例中,我們?cè)赽eforeRouteLeave守衛(wèi)中檢查是否有未保存的更改,并提示用戶是否確認(rèn)離開。如果用戶確認(rèn)離開,則允許導(dǎo)航;否則,阻止導(dǎo)航。
到此這篇關(guān)于Vue-Router路由守衛(wèi)詳?shù)募?xì)用法教程的文章就介紹到這了,更多相關(guān)Vue-Router路由守衛(wèi)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue采用EventBus實(shí)現(xiàn)跨組件通信及注意事項(xiàng)小結(jié)
EventBus是一種發(fā)布/訂閱事件設(shè)計(jì)模式的實(shí)踐。這篇文章主要介紹了vue采用EventBus實(shí)現(xiàn)跨組件通信及注意事項(xiàng),需要的朋友可以參考下2018-06-06
Vue用Export2Excel導(dǎo)出excel,多級(jí)表頭數(shù)據(jù)方式
這篇文章主要介紹了Vue用Export2Excel導(dǎo)出excel,多級(jí)表頭數(shù)據(jù)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-04-04
Vue.config.js配置報(bào)錯(cuò)ValidationError:?Invalid?options?object解
這篇文章主要給大家介紹了關(guān)于Vue.config.js配置報(bào)錯(cuò)ValidationError:?Invalid?options?object的解決辦法,主要由于vue.config.js配置文件錯(cuò)誤導(dǎo)致的,文中通過代碼介紹的非常詳細(xì),需要的朋友可以參考下2024-02-02
vue 實(shí)現(xiàn) rem 布局或vw 布局的方法
這篇文章主要介紹了vue 實(shí)現(xiàn) rem 布局的 或者 vw 布局的方法,本文給提供多種方法,需要的朋友可以參考下2019-11-11
vue.config.js中devServer.proxy配置說明及配置正確不生效問題解決
Vue項(xiàng)目devServer.proxy代理配置詳解的是一個(gè)非常常見的需求,下面這篇文章主要給大家介紹了關(guān)于vue.config.js中devServer.proxy配置說明及配置正確不生效問題解決的相關(guān)資料,需要的朋友可以參考下2023-02-02

