一文詳解Vue Router的使用和路由守衛(wèi)
Vue Router 是 Vue.js 的官方路由庫(kù),用于在 Vue 應(yīng)用中實(shí)現(xiàn)單頁(yè)面應(yīng)用(SPA)的客戶端路由。它使得 Vue 應(yīng)用能夠在不重新加載頁(yè)面的情況下實(shí)現(xiàn)不同的視圖和狀態(tài)切換。以下是 Vue Router 的詳細(xì)介紹,包括基本概念、配置、路由導(dǎo)航以及高級(jí)用法。
1 基本概念
路由 (Route): 路由是 URL 與 Vue 組件之間的映射關(guān)系。每個(gè)路由配置關(guān)聯(lián)一個(gè)視圖組件。
路由表 (Router Table): 路由表是一個(gè)數(shù)組,定義了路由的配置。每個(gè)路由配置項(xiàng)包括路徑、組件及其他參數(shù)。
路由實(shí)例 (Router Instance): 一個(gè) Vue Router 實(shí)例,負(fù)責(zé)管理路由配置、導(dǎo)航和路由狀態(tài)。
路由視圖 (Router View): 一個(gè) Vue 組件,作為路由組件的容器,渲染與當(dāng)前路由匹配的組件。
- - 安裝
首先,安裝 Vue Router:
npm install vue-router
- 配置和使用
創(chuàng)建路由實(shí)例
創(chuàng)建一個(gè) router/index.js 文件,定義路由配置并創(chuàng)建路由實(shí)例:
import { createRouter, createWebHistory } from 'vue-router'; import Home from '../views/Home.vue'; import About from '../views/About.vue'; const routes = [ { path: '/', component: Home }, { path: '/about', component: About } ]; const router = createRouter({ history: createWebHistory(), routes }); export default router;
- 在 Vue 應(yīng)用中使用路由
在 main.js 文件中導(dǎo)入路由實(shí)例,并將其傳遞給 Vue 應(yīng)用:
import { createApp } from 'vue'; import App from './App.vue'; import router from './router'; const app = createApp(App); app.use(router); app.mount('#app');
- 使用路由視圖
在應(yīng)用的主組件 App.vue 中,使用 組件來(lái)顯示當(dāng)前路由匹配的組件:
<template> <div id="app"> <router-view></router-view> </div> </template>
2 路由導(dǎo)航
- 編程式導(dǎo)航
使用 Vue Router 提供的 router 實(shí)例進(jìn)行編程式導(dǎo)航:
// 在組件中 this.$router.push('/about'); // 或 this.$router.replace('/home');
還可以使用 router 實(shí)例的 push 和 replace 方法:
import { useRouter } from 'vue-router'; export default { setup() { const router = useRouter(); function navigateToAbout() { router.push('/about'); } return { navigateToAbout }; } }
- 聲明式導(dǎo)航
使用 組件實(shí)現(xiàn)聲明式導(dǎo)航:
<template> <nav> <router-link to="/">Home</router-link> <router-link to="/about">About</router-link> </nav> </template>
3 路由守衛(wèi)
路由守衛(wèi)是 Vue Router 提供的一種功能,允許開(kāi)發(fā)者在路由的進(jìn)入、離開(kāi)和變化過(guò)程中進(jìn)行控制和處理。通過(guò)使用路由守衛(wèi),可以在用戶導(dǎo)航到不同的路由時(shí)執(zhí)行特定的操作,例如驗(yàn)證用戶權(quán)限、處理數(shù)據(jù)加載等。Vue Router 提供了全局守衛(wèi)、路由獨(dú)享守衛(wèi)和組件內(nèi)守衛(wèi)三種類型的守衛(wèi)。
1. 全局守衛(wèi)
全局守衛(wèi)是在路由實(shí)例上定義的,適用于所有的路由。它們?cè)诼酚勺兓瘯r(shí)被調(diào)用。
- beforeEach: 在路由導(dǎo)航開(kāi)始之前調(diào)用,可以用于處理路由訪問(wèn)權(quán)限等操作。
router.beforeEach((to, from, next) => { console.log('Global beforeEach'); // 判斷是否需要登錄 if (to.meta.requiresAuth && !isAuthenticated()) { next('/login'); // 沒(méi)有權(quán)限,重定向到登錄頁(yè) } else { next(); // 允許導(dǎo)航 } });
- afterEach: 在路由導(dǎo)航結(jié)束之后調(diào)用,可以用于執(zhí)行一些不影響導(dǎo)航的操作,例如記錄日志。
router.afterEach((to, from) => { console.log('Global afterEach'); // 可用于執(zhí)行一些操作,例如更新頁(yè)面標(biāo)題 document.title = to.meta.title || 'Default Title'; });
- beforeResolve: 在路由解析完且所有組件內(nèi)守衛(wèi)和異步路由組件都已解析之后調(diào)用。適合進(jìn)行需要在導(dǎo)航完成前進(jìn)行的操作。
router.beforeResolve((to, from, next) => { console.log('Global beforeResolve'); next(); });
2. 路由獨(dú)享守衛(wèi)
路由獨(dú)享守衛(wèi)是配置在特定路由中的,只有在匹配到該路由時(shí)才會(huì)觸發(fā)。
- beforeEnter: 在路由進(jìn)入之前調(diào)用,與全局 beforeEach 類似,但僅針對(duì)特定路由。
const routes = [ { path: '/profile', component: Profile, beforeEnter: (to, from, next) => { console.log('Route beforeEnter'); if (to.meta.requiresAuth && !isAuthenticated()) { next('/login'); } else { next(); } } } ];
3. 組件內(nèi)守衛(wèi)
組件內(nèi)守衛(wèi)是定義在 Vue 組件內(nèi)部的,專用于該組件的路由守衛(wèi)。
- beforeRouteEnter: 在路由進(jìn)入之前調(diào)用,此時(shí)組件實(shí)例尚未被創(chuàng)建。通過(guò) next 函數(shù)獲取組件實(shí)例。
export default { name: 'Profile', beforeRouteEnter(to, from, next) { console.log('Component beforeRouteEnter'); // 可以獲取到組件實(shí)例 next(vm => { console.log('Component instance:', vm); }); } }
- beforeRouteUpdate: 當(dāng)路由在同一個(gè)組件中變化時(shí)調(diào)用(例如在動(dòng)態(tài)路由中),用于處理更新。
export default { name: 'Profile', beforeRouteUpdate(to, from, next) { console.log('Component beforeRouteUpdate'); // 處理路由更新邏輯 next(); } }
- beforeRouteLeave: 當(dāng)離開(kāi)當(dāng)前路由時(shí)調(diào)用,用于處理離開(kāi)前的操作,例如確認(rèn)對(duì)話框。
export default { name: 'Profile', beforeRouteLeave(to, from, next) { console.log('Component beforeRouteLeave'); // 確認(rèn)離開(kāi)操作 if (confirm('Do you really want to leave?')) { next(); } else { next(false); // 取消導(dǎo)航 } } }
4 動(dòng)態(tài)路由和嵌套路由
- 動(dòng)態(tài)路由匹配
使用 : 來(lái)定義動(dòng)態(tài)參數(shù):
const routes = [ { path: '/user/:id', component: User } ]; 在組件中通過(guò) this.$route.params 訪問(wèn)動(dòng)態(tài)參數(shù): javascript export default { computed: { userId() { return this.$route.params.id; } } }
- 嵌套路由
在路由配置中定義嵌套路徑:
const routes = [ { path: '/profile', component: Profile, children: [ { path: 'settings', component: ProfileSettings } ] } ];
在 Profile 組件中使用 顯示子路由組件:
<template> <div> <h2>Profile</h2> <router-view></router-view> </div> </template>
5 路由重定向和別名
- 重定向
路由重定向用于將訪問(wèn)某一路徑的請(qǐng)求自動(dòng)轉(zhuǎn)發(fā)到另一路徑。這對(duì)于簡(jiǎn)化 URL 或引導(dǎo)用戶到正確的頁(yè)面非常有用。
示例
假設(shè)你希望將根路徑 (/) 重定向到 /home:
const routes = [ { path: '/', redirect: '/home' }, { path: '/home', component: Home } ];
當(dāng)用戶訪問(wèn)根路徑時(shí),他們會(huì)被自動(dòng)重定向到 /home。
- 別名
路由別名允許你為一個(gè)路由配置多個(gè)路徑。使用別名可以提供不同的 URL 路徑來(lái)訪問(wèn)相同的頁(yè)面。
示例假設(shè)你有一個(gè) UserProfile 組件,且希望通過(guò)兩個(gè)不同的路徑訪問(wèn)它:
const routes = [ { path: '/user/:id', component: UserProfile, alias: '/profile/:id' // 使用別名 } ];
在這個(gè)示例中,訪問(wèn) /user/123 和 /profile/123 都會(huì)渲染 UserProfile 組件。
6 路由元信息
路由元信息是用來(lái)存儲(chǔ)與路由相關(guān)的自定義數(shù)據(jù)或信息的一個(gè)功能。這些信息不會(huì)直接影響路由的匹配,但可以用來(lái)在組件中進(jìn)行條件渲染、權(quán)限控制等操作。
如何使用路由元信息
1. 定義元信息
在定義路由時(shí),可以通過(guò) meta 屬性來(lái)添加元信息。例如:
const routes = [ { path: '/admin', component: Admin, meta: { requiresAuth: true, title: 'Admin Page' } }, { path: '/public', component: Public, meta: { title: 'Public Page' } } ];
2. 訪問(wèn)元信息
在組件中,可以通過(guò) this.$route.meta 訪問(wèn)這些元信息。例如:
export default { name: 'MyComponent', computed: { pageTitle() { return this.$route.meta.title || 'Default Title'; } } };
3. 使用元信息進(jìn)行路由守衛(wèi)
可以在全局守衛(wèi)、路由守衛(wèi)中使用元信息來(lái)控制訪問(wèn)權(quán)限或進(jìn)行其他操作。例如:
router.beforeEach((to, from, next) => { if (to.meta.requiresAuth && !isLoggedIn()) { next('/login'); } else { next(); } });
7 路由懶加載
路由懶加載是一種優(yōu)化策略,用于減少初始加載時(shí)間和提高應(yīng)用性能。通過(guò)將路由組件按需加載,而不是一次性加載所有組件,可以加快應(yīng)用的響應(yīng)速度和啟動(dòng)時(shí)間。
- 使用動(dòng)態(tài)導(dǎo)入
使用 import() 函數(shù)來(lái)實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)入組件。在 Vue Router 中,可以將路由組件設(shè)置為懶加載的形式:
{ name: 'information', path: '/information', component: () => import('@/view/app/information/Main') },
路由懶加載的好處
- 減少初始加載時(shí)間:只有在用戶訪問(wèn)特定路由時(shí),相關(guān)的組件才會(huì)被加載。
- 提高應(yīng)用性能:減輕主線程負(fù)擔(dān),提升用戶體驗(yàn)。
- 按需加載:根據(jù)用戶的導(dǎo)航行為加載所需的組件,優(yōu)化資源使用。
結(jié)論
Vue Router 提供了豐富的功能來(lái)管理 Vue 應(yīng)用中的路由。通過(guò)靈活配置路由、使用導(dǎo)航守衛(wèi)、動(dòng)態(tài)路由以及嵌套路由等功能,可以創(chuàng)建功能強(qiáng)大且用戶體驗(yàn)良好的單頁(yè)面應(yīng)用。
相關(guān)文章
vue props default Array或是Object的正確寫法說(shuō)明
這篇文章主要介紹了vue props default Array或是Object的正確寫法說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-07-07vue再次進(jìn)入頁(yè)面不會(huì)再次調(diào)用接口請(qǐng)求問(wèn)題
這篇文章主要介紹了vue再次進(jìn)入頁(yè)面不會(huì)再次調(diào)用接口請(qǐng)求問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-08-08vue el-select綁定對(duì)象時(shí),回顯內(nèi)容不正確,始終是最后一項(xiàng)的解決
這篇文章主要介紹了vue el-select綁定對(duì)象時(shí),回顯內(nèi)容不正確,始終是最后一項(xiàng)的問(wèn)題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07詳解vue-Resource(與后端數(shù)據(jù)交互)
本篇文章主要介紹了vue-Resource(與后端數(shù)據(jù)交互),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2017-01-01基于Vue.js+Nuxt開(kāi)發(fā)自定義彈出層組件
這篇文章主要介紹了基于Vue.js+Nuxt開(kāi)發(fā)自定義彈出層組件,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-10-10利用vue + koa2 + mockjs模擬數(shù)據(jù)的方法教程
這篇文章主要給大家介紹了關(guān)于利用vue + koa2 + mockjs模擬數(shù)據(jù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2017-11-11vue3?實(shí)現(xiàn)右鍵菜單編輯復(fù)制粘貼功能
在瀏覽器中,Vue3編輯器自帶默認(rèn)右鍵菜單,然而,在Electron桌面應(yīng)用中,這一功能需自行編寫代碼實(shí)現(xiàn),本文詳細(xì)介紹了如何在Vue3中手動(dòng)實(shí)現(xiàn)右鍵菜單的編輯、復(fù)制、粘貼功能,并提供了代碼示例,更多細(xì)節(jié)和相關(guān)教程可參考腳本之家的其他文章2024-10-10