Vue路由深度解析:Vue Router與導航守衛

Vue路由深度解析:Vue Router與導航守衛

一、Vue Router基礎與安裝配置

1. Vue Router核心概念

Vue Router是Vue.js官方的路由管理器,主要功能包括:

  • 嵌套路由映射
  • 模塊化的路由配置
  • 路由參數、查詢、通配符
  • 細粒度的導航控制
  • 自動激活的CSS類鏈接
  • HTML5 history模式或hash模式
  • 可定制的滾動行為

2. 安裝與基本配置

安裝Vue Router

npm install vue-router@4
# 或
yarn add vue-router@4

基礎配置示例

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'const routes = [{path: '/',name: 'home',component: HomeView},{path: '/about',name: 'about',// 路由級代碼拆分component: () => import('../views/AboutView.vue')}
]const router = createRouter({history: createWebHistory(process.env.BASE_URL),routes
})export default router

在main.js中引入

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'const app = createApp(App)
app.use(router)
app.mount('#app')

二、路由模式與路由配置詳解

1. 路由模式對比

模式特點示例
Hash模式使用URL hash模擬完整URLhttp://example.com/#/about
History模式使用HTML5 History APIhttp://example.com/about
Memory模式不修改URL,適合非瀏覽器環境(如Electron)無URL變化

配置示例

import { createWebHashHistory,  // Hash模式createWebHistory,     // History模式createMemoryHistory   // Memory模式
} from 'vue-router'const router = createRouter({history: createWebHistory(), // 推薦生產環境使用// history: createWebHashHistory(), // 兼容性更好// history: createMemoryHistory(), // 非瀏覽器環境routes
})

2. 動態路由與參數傳遞

動態路由配置

const routes = [// 動態字段以冒號開始{path: '/user/:id',name: 'user',component: UserView},// 可匹配/user/123或/user/456{path: '/user/:id/posts/:postId',component: UserPostView}
]

參數獲取方式

<template><!-- 在模板中直接使用 --><div>用戶ID: {{ $route.params.id }}</div>
</template><script setup>
import { useRoute } from 'vue-router'// 在setup中使用
const route = useRoute()
console.log(route.params.id)
</script><script>
// 在Options API中使用
export default {created() {console.log(this.$route.params.id)}
}
</script>

3. 嵌套路由與命名視圖

嵌套路由配置

const routes = [{path: '/user/:id',component: UserLayout,children: [{path: '', // 默認子路由component: UserProfile},{path: 'posts',component: UserPosts},{path: 'settings',component: UserSettings}]}
]

命名視圖(多路由出口)

const routes = [{path: '/',components: {default: HomeView, // 默認出口sidebar: SidebarView, // <router-view name="sidebar">footer: AppFooter  // <router-view name="footer">}}
]

三、導航守衛全面解析

1. 導航守衛類型與執行流程

完整的導航解析流程

  1. 導航被觸發
  2. 調用beforeRouteLeave守衛(組件內)
  3. 調用全局beforeEach守衛
  4. 在重用的組件里調用beforeRouteUpdate守衛(組件內)
  5. 調用路由配置里的beforeEnter守衛
  6. 解析異步路由組件
  7. 在被激活的組件里調用beforeRouteEnter(組件內)
  8. 調用全局beforeResolve守衛
  9. 導航被確認
  10. 調用全局afterEach鉤子
  11. 觸發DOM更新
  12. 調用beforeRouteEnter守衛中傳給next的回調函數

2. 全局守衛

// router/index.js// 全局前置守衛
router.beforeEach((to, from, next) => {console.log('全局前置守衛', to, from)// 必須調用next()繼續導航next()
})// 全局解析守衛
router.beforeResolve((to, from, next) => {console.log('全局解析守衛', to, from)next()
})// 全局后置鉤子
router.afterEach((to, from) => {console.log('全局后置鉤子', to, from)// 不需要next函數
})

3. 路由獨享守衛

const routes = [{path: '/admin',component: AdminView,beforeEnter: (to, from, next) => {// 僅在此路由觸發if (isAdmin()) next()else next('/login')}}
]

4. 組件內守衛

<script>
export default {beforeRouteEnter(to, from, next) {// 在渲染該組件的對應路由被驗證前調用// 不能獲取組件實例 `this`next(vm => {// 通過 `vm` 訪問組件實例console.log(vm.someData)})},beforeRouteUpdate(to, from) {// 當前路由改變,但是該組件被復用時調用// 可以訪問組件實例 `this`this.fetchData(to.params.id)},beforeRouteLeave(to, from) {// 導航離開該組件的對應路由時調用// 可以訪問組件實例 `this`const answer = window.confirm('確定要離開嗎?未保存的更改將會丟失')if (!answer) return false}
}
</script>

5. 導航守衛實戰:權限控制

// router/index.js
import { useAuthStore } from '@/stores/auth'const routes = [{path: '/',name: 'home',component: HomeView,meta: { requiresAuth: false }},{path: '/dashboard',name: 'dashboard',component: DashboardView,meta: { requiresAuth: true,roles: ['admin', 'editor'] }},{path: '/admin',name: 'admin',component: AdminView,meta: { requiresAuth: true,roles: ['admin'] }}
]router.beforeEach(async (to, from, next) => {const authStore = useAuthStore()const isAuthenticated = authStore.isAuthenticatedconst userRole = authStore.user?.role || 'guest'// 檢查路由是否需要認證if (to.meta.requiresAuth && !isAuthenticated) {return next({ name: 'login', query: { redirect: to.fullPath } })}// 檢查路由角色權限if (to.meta.roles && !to.meta.roles.includes(userRole)) {return next({ name: 'forbidden' })}// 如果用戶已登錄但要去登錄頁,重定向到首頁if (to.name === 'login' && isAuthenticated) {return next({ name: 'home' })}next()
})

四、路由高級特性

1. 路由元信息與過渡動畫

路由元信息配置

const routes = [{path: '/posts',component: PostsLayout,meta: { requiresAuth: true,transition: 'slide-left' },children: [{path: 'new',component: NewPost,meta: { transition: 'slide-up',requiresAdmin: true }}]}
]

動態過渡效果

<template><router-view v-slot="{ Component, route }"><transition :name="route.meta.transition || 'fade'"><component :is="Component" /></transition></router-view>
</template><style>
.fade-enter-active,
.fade-leave-active {transition: opacity 0.3s ease;
}.fade-enter-from,
.fade-leave-to {opacity: 0;
}.slide-left-enter-active,
.slide-left-leave-active {transition: transform 0.3s ease;
}.slide-left-enter-from {transform: translateX(100%);
}.slide-left-leave-to {transform: translateX(-100%);
}.slide-up-enter-active,
.slide-up-leave-active {transition: transform 0.3s ease;
}.slide-up-enter-from {transform: translateY(100%);
}.slide-up-leave-to {transform: translateY(-100%);
}
</style>

2. 滾動行為控制

const router = createRouter({history: createWebHistory(),routes,scrollBehavior(to, from, savedPosition) {// 返回滾動位置對象if (savedPosition) {return savedPosition // 瀏覽器前進/后退時恢復位置}if (to.hash) {return {el: to.hash, // 滾動到錨點behavior: 'smooth' // 平滑滾動}}if (to.meta.scrollToTop) {return { top: 0 } // 新路由滾動到頂部}// 默認不改變滾動位置}
})

3. 路由懶加載與分包

基礎懶加載

const routes = [{path: '/about',component: () => import('../views/AboutView.vue')}
]

自定義分包

const routes = [{path: '/admin',component: () => import(/* webpackChunkName: "admin" */ '../views/AdminView.vue'),children: [{path: 'dashboard',component: () => import(/* webpackChunkName: "admin" */ '../views/AdminDashboard.vue')}]},{path: '/user/:id',component: () => import(/* webpackChunkName: "user" */ '../views/UserView.vue')}
]

4. 動態路由API

添加路由

router.addRoute({path: '/new-route',name: 'newRoute',component: () => import('../views/NewView.vue')
})// 添加到現有路由的子路由
router.addRoute('parentRoute', {path: 'child',component: () => import('../views/ChildView.vue')
})

刪除路由

// 通過名稱刪除
router.removeRoute('routeName')// 通過添加返回的回調刪除
const removeRoute = router.addRoute(routeConfig)
removeRoute() // 刪除路由

檢查路由

// 檢查路由是否存在
router.hasRoute('routeName')// 獲取所有路由記錄
router.getRoutes()

五、常見問題與最佳實踐

1. 常見問題解決方案

問題1:路由重復跳轉報錯

// 統一處理導航錯誤
router.onError((error) => {if (error.message.includes('Avoided redundant navigation')) {// 忽略重復導航錯誤} else {// 處理其他導航錯誤}
})

問題2:動態路由刷新404

  • History模式需要服務器配置支持
  • Nginx配置示例:
    location / {try_files $uri $uri/ /index.html;
    }
    

問題3:路由組件不更新

// 使用beforeRouteUpdate或監聽$route
watch(() => route.params.id,(newId) => {fetchData(newId)}
)

2. 最佳實踐建議

  1. 路由組織

    • 按功能模塊組織路由文件
    • 使用路由元信息(meta)存儲權限、標題等信息
    • 對大型項目考慮自動導入路由
  2. 性能優化

    • 合理使用路由懶加載
    • 對頻繁訪問的路由考慮預加載
    • 避免在導航守衛中進行繁重操作
  3. 安全實踐

    • 始終驗證前端路由權限
    • 敏感路由應在后端再次驗證
    • 使用路由獨享守衛處理特殊權限
  4. 開發體驗

    • 為路由添加name屬性方便跳轉
    • 使用路由元信息管理頁面標題
    • 實現進度條提升用戶體驗

六、綜合實戰:企業級路由方案

1. 完整路由配置示例

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import { useAuthStore } from '@/stores/auth'
import NProgress from 'nprogress'const routes = [{path: '/',name: 'home',component: () => import('@/views/HomeView.vue'),meta: {title: '首頁',requiresAuth: false,cache: true}},{path: '/login',name: 'login',component: () => import('@/views/LoginView.vue'),meta: {title: '登錄',guestOnly: true}},{path: '/dashboard',name: 'dashboard',component: () => import('@/views/DashboardView.vue'),meta: {title: '儀表盤',requiresAuth: true}},{path: '/admin',name: 'admin',component: () => import('@/views/layouts/AdminLayout.vue'),meta: {title: '管理后臺',requiresAuth: true,roles: ['admin']},children: [{path: '',name: 'admin-dashboard',component: () => import('@/views/admin/DashboardView.vue'),meta: { title: '控制臺' }},{path: 'users',name: 'admin-users',component: () => import('@/views/admin/UsersView.vue'),meta: { title: '用戶管理' }}]},{path: '/:pathMatch(.*)*',name: 'not-found',component: () => import('@/views/NotFoundView.vue'),meta: {title: '頁面不存在'}}
]const router = createRouter({history: createWebHistory(import.meta.env.BASE_URL),routes,scrollBehavior(to, from, savedPosition) {if (savedPosition) return savedPositionif (to.hash) return { el: to.hash, behavior: 'smooth' }return { top: 0 }}
})// 進度條配置
NProgress.configure({ showSpinner: false })// 全局前置守衛
router.beforeEach(async (to, from, next) => {NProgress.start()const authStore = useAuthStore()const isAuthenticated = authStore.isAuthenticatedconst userRole = authStore.user?.role || 'guest'// 設置頁面標題document.title = to.meta.title ? `${to.meta.title} | 我的應用` : '我的應用'// 檢查認證if (to.meta.requiresAuth && !isAuthenticated) {return next({name: 'login',query: { redirect: to.fullPath }})}// 檢查角色權限if (to.meta.roles && !to.meta.roles.includes(userRole)) {return next({ name: 'forbidden' })}// 已登錄用戶訪問guestOnly路由if (to.meta.guestOnly && isAuthenticated) {return next({ name: 'home' })}next()
})// 全局后置鉤子
router.afterEach(() => {NProgress.done()
})export default router

2. 路由工具函數

// utils/router.js
export function resetRouter() {const newRouter = createRouter()router.matcher = newRouter.matcher // 重置路由
}export function loadRoutesByRole(role) {const dynamicRoutes = []if (role === 'admin') {dynamicRoutes.push({path: '/admin',component: () => import('@/views/AdminView.vue'),children: [// 管理員專屬路由]})}dynamicRoutes.forEach(route => {router.addRoute(route)})
}export function getRouteTitle(route) {return route.meta.title || ''
}

3. 路由與狀態管理集成

// stores/app.js
import { defineStore } from 'pinia'
import { useRouter } from 'vue-router'export const useAppStore = defineStore('app', {state: () => ({cachedViews: [],visitedViews: []}),actions: {addCachedView(view) {if (this.cachedViews.includes(view.name)) returnif (view.meta?.cache) {this.cachedViews.push(view.name)}},addVisitedView(view) {const existing = this.visitedViews.find(v => v.path === view.path)if (existing) {if (existing.fullPath !== view.fullPath) {// 更新現有記錄Object.assign(existing, view)}return}this.visitedViews.push(Object.assign({}, view, {title: view.meta?.title || '未知'}))},async logout() {const router = useRouter()// 清理狀態this.$reset()// 重定向到登錄頁await router.push('/login')}}
})

通過本指南,您已經全面掌握了Vue Router的核心概念和高級用法。從基礎配置到導航守衛,從動態路由到狀態集成,這些知識將幫助您構建復雜且高效的單頁應用程序。實際項目中應根據具體需求選擇合適的路由方案,并遵循最佳實踐以確保應用的性能和可維護性。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/906181.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/906181.shtml
英文地址,請注明出處:http://en.pswp.cn/news/906181.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

前后端分離微服務架構

前后端分離微服務架構 介紹: 前端通過Vue和ElementUI構建界面&#xff0c;使用axios調用后端API。Nginx作為反向代理&#xff0c;將請求路由到Zuul網關。Zuul進行權限驗證&#xff08;JWT&#xff09;后&#xff0c;將請求分發到微服務。(身份驗證,安全防護(sql注入,xxs跨網站…

iOS 工廠模式

iOS 工廠模式 文章目錄 iOS 工廠模式前言工廠模式簡單工廠案例場景分析蘋果類優點缺點 小結 工廠模式客戶端調用**優點****缺點** 抽象工廠模式三個模式對比 前言 筆者之前學習了有關于設計模式的六大原則,之前簡單了解過這個工廠模式,今天主要是重新學習一下這個模式,正式系統…

【機器學習】工具入門:飛牛啟動Dify Ollama Deepseek

很久沒有更新文章了,最近正好需要研究一些機器學習的東西&#xff0c;打算研究一下 difyOllama 以下是基于FN 的dify本地化部署&#xff0c;當然這也可能是全網唯一的飛牛部署dify手冊 部署 官方手冊&#xff1a;https://docs.dify.ai/en/getting-started/install-self-hos…

安卓A15系統實現修改鎖屏界面默認壁紙功能

最近遇到一個A15系統項目&#xff0c;客戶要求修改鎖屏界面的默認壁紙&#xff0c;客戶提供了一張壁紙圖片&#xff0c;但是從A15系統的源代碼查看時才知道谷歌已經去掉了相關的代碼&#xff0c;已經不支持了&#xff0c;A13和A14系統好像是支持的&#xff0c;A15系統的Wallpap…

從理論到實戰:模糊邏輯算法的深度解析與應用實踐

從理論到實戰&#xff1a;模糊邏輯算法的深度解析與應用實踐 一、模糊邏輯的核心概念與數學基礎 模糊邏輯&#xff08;Fuzzy Logic&#xff09;是一種處理不確定性的數學工具&#xff0c;其核心思想是將傳統布爾邏輯的“非黑即白”擴展為連續的隸屬度函數。例如&#xff0c;在…

正向代理與反向代理區別及應用

正向代理和反向代理是兩種常見的代理服務器類型&#xff0c;它們在網絡架構中扮演不同角色&#xff0c;核心區別在于代理對象和使用場景。 1. 正向代理&#xff08;Forward Proxy&#xff09; 定義&#xff1a;正向代理是客戶端&#xff08;如瀏覽器&#xff09;主動配置的代理…

OpenCV CUDA模塊中逐元素操作------邏輯運算

操作系統&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 編程語言&#xff1a;C11 算法描述 比較、AND、OR、NOT等。這類操作可用于創建基于條件的掩碼&#xff0c;這對于圖像分割或特征選擇非常有用。 主要函數 1. 按位與 (cv::cuda::b…

一臺入網的電腦有6要素, 機器名,mac,ip,俺碼,網關,dns,分別有什么作用

一臺入網的電腦需要配置的 六大網絡要素&#xff08;機器名、MAC地址、IP地址、子網掩碼、網關、DNS&#xff09;各自承擔不同的關鍵作用&#xff0c;共同確保設備能正確通信和訪問網絡資源。以下是它們的詳細功能解析&#xff1a; 1. 機器名&#xff08;主機名&#xff09; 作…

MySQL之儲存引擎和視圖

一、儲存引擎 基本介紹&#xff1a; 1、MySQL的表類型由儲存引擎(Storage Engines)決定&#xff0c;主要包括MyISAM、innoDB、Memory等。 2、MySQL數據表主要支持六種類型&#xff0c;分別是&#xff1a;CSV、Memory、ARCHIVE、MRG_MYISAN、MYISAM、InnoBDB。 3、這六種又分…

【Spring Boot后端組件】mybatis-plus使用

文章目錄 mybatis-plus使用一、依賴引入二、添加相關配置項三、功能詳解1.自增主鍵2.邏輯刪除3.操作時間自動填充4.其他字段自動填充5.分頁查詢6.自定義動態查詢7.代碼生成器8.代碼生成器(自定義模板) mybatis-plus使用 一、依賴引入 pom.xml文件 <?xml version"1.…

docker compose 啟動指定的 service

使用 Docker Compose 啟動指定服務 要在 Docker Compose 中啟動特定的服務而不是所有服務&#xff0c;可以使用以下命令&#xff1a; docker compose up [服務名] 基本用法 啟動單個服務&#xff1a; docker compose up service_name 啟動多個指定服務&#xff1a; docker …

wordcount程序

### 在 IntelliJ IDEA 中編寫和運行 Spark WordCount 程序 要使用 IntelliJ IDEA 編寫并運行 Spark 的 WordCount 程序&#xff0c;需按照以下流程逐步完成環境配置、代碼編寫以及任務提交。 --- #### 1. **安裝與配置 IntelliJ IDEA** 確保已正確安裝 IntelliJ IDEA&#x…

SmartETL函數式組件的設計與應用

SmartETL框架主要采用了面向對象的設計思想&#xff0c;將ETL過程中的處理邏輯抽象為Loader和Processor&#xff08;對應loader模塊和iterator模塊&#xff09;&#xff0c;所有流程組件需要繼承或實現DataProvider&#xff08;iter方法&#xff09;或JsonIterator&#xff08;…

鴻蒙AI開發:10-多模態大模型與原子化服務的集成

鴻蒙AI開發&#xff1a;10-多模態大模型與原子化服務的集成 在鴻蒙生態中&#xff0c;多模態大模型與原子化服務的集成是一個重要課題。本文將介紹如何在鴻蒙平臺上進行多模態大模型與原子化服務的集成&#xff0c;以及相關的技術細節和實際案例。 鴻蒙AI開發概述 什么是鴻蒙AI…

python打卡day29@浙大疏錦行

知識點回顧 類的裝飾器裝飾器思想的進一步理解&#xff1a;外部修改、動態類方法的定義&#xff1a;內部定義和外部定義 作業&#xff1a;復習類和函數的知識點&#xff0c;寫下自己過去29天的學習心得&#xff0c;如對函數和類的理解&#xff0c;對python這門工具的理解等&…

20250516使用TF卡將NanoPi NEO core開發板出廠的Ubuntu core22.04.3系統降級到Ubuntu core16.04.2

20250516使用TF卡將NanoPi NEO core開發板出廠的Ubuntu core22.04.3系統降級到Ubuntu core16.04.2 2025/5/16 10:58 緣起&#xff1a;NanoPi NEO core核心板出廠預制的OS操作系統為Ubuntu core22.04.3系統。 【雖然是友善之臂提供的最新的系統&#xff0c;但是缺少很多用用程序…

密西根大學新作——LightEMMA:自動駕駛中輕量級端到端多模態模型

導讀 目前將自動駕駛與視覺語言模型&#xff08;VLMs&#xff09;結合的研究越來越火熱&#xff0c;VLMs已經證明了其對自動駕駛的重要作用。本文引入了一種用于自動駕駛的輕量級端到端多模態模型LightEMMA&#xff0c;它能夠集成和評估當前的商業和開源模型&#xff0c;以研究…

框架之下再看HTTP請求對接后端method

在當今的軟件開發領域&#xff0c;各類框架涌現&#xff0c;極大地提升了開發效率。以 Java 開發為例&#xff0c;Spring 框架不斷演進&#xff0c;Spring Boot 更是簡化到只需引入 Maven 包&#xff0c;添加諸如SpringBootApplication、RestController等注解&#xff0c;就能輕…

Vue+Go 自定義打字素材的打字網站

Typing_Key_Board 這是一個基于Vue 3和Go語言的自定義素材打字練習網站&#xff0c;靈感來源于常用字打字練習&#xff0c;解決了大多數網站無法自定義打字素材的問題。在 Typing_Key_Board (簡稱TKB)中&#xff0c;用戶可以自定義打字素材進行練習&#xff0c;在復習代碼的同…

開源物聯網平臺(OpenRemote)

在物聯網技術蓬勃發展的當下&#xff0c;OpenRemote作為一款強大的開源物聯網平臺&#xff0c;正逐漸在多個領域嶄露頭角。尤其是在智能能源管理領域&#xff0c;它為微電網和分布式能源網絡提供了全面且靈活的數據集成與管理方案&#xff0c;展現出獨特的優勢。 OpenRemote提供…