Vue2下

六:vue-router (重要)

(一). 對路由的理解

1.什么是路由


路由(Router) 是管理頁面跳轉和 URL 與視圖映射關系的機制,核心作用是:根據不同的 URL 路徑,展示對應的頁面內容,實現單頁應用(SPA)的頁面切換

一個路由就是一組對應關系(key—value)。
key為路徑,value可能是function或component。
在這里插入圖片描述

核心概念:

  1. URL 與視圖的映射
    路由會將 URL 路徑(如 /home/about)與對應的組件(頁面)關聯起來,當 URL 變化時,自動渲染匹配的組件,而無需刷新整個頁面(這是 SPA 的核心特性)。

  2. 單頁應用(SPA)的基礎
    傳統多頁應用通過服務器返回不同 HTML 頁面實現跳轉,而路由讓 SPA 能在一個 HTML 頁面內,通過切換組件模擬多頁效果,提升用戶體驗(減少加載時間)。

以下是對圖片內容的提取與整理,清晰區分后端路由前端路由的核心差異:

2.路由分類

2.1. 后端路由
  • 理解

    • 路由的 value函數,專門處理客戶端(如瀏覽器)的請求。
    • 作用:服務器接收到請求后,通過路徑匹配對應的處理函數,返回數據或頁面。
  • 工作過程

    1. 客戶端(瀏覽器)發送請求(如 GET /api/users)。
    2. 服務器根據請求路徑,找到匹配的函數(如 Node.js 的 app.get('/api/users', (req, res) => { ... }) )。
    3. 函數處理請求(查數據庫、拼接數據等),返回響應(如 JSON 數據、HTML 頁面)。
2.2. 前端路由
  • 理解

    • 路由的 value組件(component),用于動態展示頁面內容(SPA 單頁應用的核心)。
    • 作用:在瀏覽器端實現頁面切換,無需刷新整個頁面。
  • 工作過程

    1. 瀏覽器的 URL 路徑變化(如從 /home/about)。
    2. 前端路由根據路徑變化,匹配對應的組件(如 Vue 中 vue-router 的配置)。
    3. 匹配的組件渲染到頁面,實現“局部更新”(無需服務器參與)。
2.3核心差異對比
對比項后端路由前端路由
處理位置服務器端瀏覽器端
value 類型函數(處理請求、返回響應)組件(展示頁面內容)
頁面刷新每次請求可能刷新整個頁面僅局部更新,無整頁刷新
典型技術Node.js(Express)、Java(SpringMVC)Vue Router、React Router
2.4總結
  • 后端路由:負責“服務器如何響應請求”,用函數處理路徑并返回數據/頁面。
  • 前端路由:負責“瀏覽器如何切換內容”,用組件匹配路徑并局部更新頁面。

前端路由是 SPA 應用的基礎,讓頁面跳轉像“切換組件”一樣絲滑~

3.前端路由的實現原理

主要依賴兩種瀏覽器特性:

  • hash 模式:利用 URL 中的 # 后面的部分(如 http://xxx.com/#/home),hash 變化不會觸發頁面刷新,通過 onhashchange 事件監聽變化。
  • history 模式:使用 HTML5 的 history API(如 pushStatereplaceState),可以修改 URL 且不發送請求,通過 popstate 事件監聽變化。

(二).路由高級

  • 嵌套路由(children數組,配置子路由規則,對應組件內用<router-view>顯示 )
  • 路由守衛:全局守衛(router.beforeEach )、組件內守衛(beforeRouteEnter等 )、路由獨享守衛(beforeEnter ),用于權限校驗、導航控制
  • 路由懶加載(component: () => import('./MyRoute.vue') ):優化首屏加載速度

1.嵌套(多級)路由

1.嵌套路由,也叫子路由,是指在一個路由組件中,還可以再嵌套其他的路由組件。在 Vue Router 中,它能夠幫助構建更加復雜且層次分明的單頁應用結構,讓頁面的組織和導航更加清晰。

應用場景

當頁面存在層級關系時,適合使用嵌套路由。比如電商網站中,商品詳情頁是一個大的頁面,在商品詳情頁中,又可以有商品介紹、用戶評價、相關推薦等子頁面,這些子頁面就可以通過嵌套路由來實現。

配置步驟(以 Vue Router 在 Vue 項目中的使用為例)
1. 定義路由配置

router/index.js 文件中(假設這是路由配置文件),進行如下配置:

import Vue from 'vue'
import VueRouter from 'vue-router'
import ParentComponent from '../components/ParentComponent.vue'
import ChildComponent1 from '../components/ChildComponent1.vue'
import ChildComponent2 from '../components/ChildComponent2.vue'Vue.use(VueRouter)const routes = [{path: '/parent',component: ParentComponent,children: [{path: 'child1',component: ChildComponent1},{path: 'child2',component: ChildComponent2}]}
]const router = new VueRouter({routes
})export default router

在上述代碼中,定義了一個父路由 '/parent',其對應的組件是 ParentComponent。在 children 數組中,又定義了兩個子路由 'child1''child2',分別對應 ChildComponent1ChildComponent2

2. 父組件中設置路由出口

ParentComponent.vue 中,需要設置 <router-view> 來顯示子路由對應的組件:

<template><div><h1>這是父組件</h1><router-link to="/parent/child1">子組件1</router-link><router-link to="/parent/child2">子組件2</router-link><router-view></router-view></div>
</template>

這里通過 <router-link> 創建了導航鏈接,點擊鏈接時,會在 <router-view> 中顯示對應的子路由組件。

訪問嵌套路由

當訪問 http://localhost:8080/parent/child1 時,會顯示 ParentComponent 的內容,同時在 <router-view> 中渲染 ChildComponent1 的內容;訪問 http://localhost:8080/parent/child2 時,則渲染 ChildComponent2 的內容。

嵌套路由的注意事項
  • 子路由路徑:子路由的路徑不要加 / 開頭,否則會被當作根路徑。
  • 嵌套層級:可以根據實際需求進行多層嵌套,但層級過深可能會使代碼復雜度增加,維護起來更困難。
  • 路由匹配規則:當訪問父路由時,如果沒有匹配到具體的子路由,<router-view> 中不會渲染任何內容,有時需要設置一個默認子路由來避免這種情況,比如:
{path: '/parent',component: ParentComponent,children: [{path: '', // 空字符串表示默認子路由component: ChildComponent1},{path: 'child1',component: ChildComponent1},{path: 'child2',component: ChildComponent2}]
}

這樣,當訪問 /parent 時,會默認顯示 ChildComponent1 的內容。

通過嵌套路由,可以讓單頁應用的頁面結構更加清晰合理,提升用戶體驗和代碼的可維護性。

2.路由守衛

在 Vue Router 中,路由守衛是一種非常強大的功能,用于在路由跳轉的不同階段對導航進行攔截和控制,例如進行權限驗證、記錄日志、動態修改路由等。路由守衛主要分為全局守衛路由獨享守衛組件內守衛三類。以下是詳細介紹:

2.1全局守衛

全局守衛會對應用中所有的路由跳轉起作用,主要包括以下三種:

  • router.beforeEach
    • 觸發時機:在路由跳轉之前,每次路由切換都會觸發,并且是全局前置守衛,可以對即將發生的導航進行攔截。
    • 參數:接收三個參數,分別是to(即將要進入的目標路由對象)、from(當前導航正要離開的路由對象)、next(一個函數,必須調用它來resolve這個鉤子。執行順序決定了路由是否繼續跳轉 )。
    • 示例
const router = new VueRouter({...})router.beforeEach((to, from, next) => {// 模擬權限驗證,假設用戶登錄后才有權限訪問除登錄頁外的其他頁面const isLoggedIn = localStorage.getItem('token'); if (to.path!== '/login' &&!isLoggedIn) {next('/login'); // 未登錄則重定向到登錄頁} else {next(); // 允許訪問,繼續跳轉}
})
  • router.beforeResolve
    • 觸發時機:在導航被確認之前,在所有組件內守衛和異步路由組件被解析之后,beforeEach 之后觸發。主要用于確保在導航確認之前,所有異步操作都已經完成。
    • 參數:和beforeEach 一樣,包含tofromnext
    • 示例
router.beforeResolve((to, from, next) => {if (to.meta.requiresAsyncData) {// 假設這里有一個異步獲取數據的函數fetchAsyncData(to.params.id).then(() => {next();}).catch(() => {next(false);});} else {next();}
});
  • router.afterEach
    • 觸發時機:在路由跳轉完成之后觸發,沒有next 函數,不能對導航進行攔截,主要用于進行一些不需要對導航進行干預的操作,比如記錄頁面訪問日志。
    • 參數:接收兩個參數,分別是to(成功跳轉的目標路由對象)、from(離開的路由對象)。
    • 示例
router.afterEach((to, from) => {console.log(`${from.path} 跳轉到了 ${to.path}`);// 可以在這里調用接口記錄頁面訪問日志等操作
})

在 Vue Router 中,全局守衛是作用于整個應用所有路由的導航鉤子,用于統一處理路由跳轉的權限驗證、日志記錄、數據預處理等邏輯。全局守衛分為三類,分別在路由跳轉的不同階段觸發,以下是詳細解析:

一、全局前置守衛(beforeEach
作用

路由跳轉前觸發,是全局守衛中最常用的一種,主要用于攔截導航、驗證權限、重定向等操作。

觸發時機
  • 每次路由切換(包括初始化時的首次加載)都會觸發。
  • 執行順序:在所有組件內守衛和路由獨享守衛之前。
參數
  • to:即將進入的目標路由對象(包含路徑、參數、元信息等)。
  • from:當前正要離開的路由對象。
  • next:函數,必須調用以決定導航行為:
    • next():允許導航繼續。
    • next(false):取消導航,停留在當前頁面。
    • next('/path')next({ name: 'routeName' }):重定向到指定路由。
    • next(error):傳遞錯誤對象,會被全局錯誤處理器捕獲。
示例(權限驗證)
const router = new VueRouter({... })// 全局前置守衛:驗證用戶是否登錄
router.beforeEach((to, from, next) => {// 1. 登錄頁無需驗證,直接放行if (to.path === '/login') {next();return;}// 2. 非登錄頁:檢查是否有登錄憑證(如 token)const token = localStorage.getItem('token');if (token) {// 已登錄:允許進入目標路由next();} else {// 未登錄:強制重定向到登錄頁next('/login');}
});
二、全局解析守衛(beforeResolve
作用

導航被確認前觸發,用于確保所有異步操作(如組件加載、數據請求)完成后再進入目標路由。

觸發時機
  • beforeEach 之后,afterEach 之前。
  • 會等待所有組件內守衛和異步路由組件解析完成后才執行。
參數

beforeEach 相同(tofromnext)。

示例(預處理數據)
// 全局解析守衛:確保數據加載完成
router.beforeResolve(async (to, from, next) => {// 如果路由需要預加載數據(通過 meta 標記)if (to.meta.needPreload) {try {// 異步加載數據await fetchData(to.params.id);next(); // 數據加載完成,允許導航} catch (error) {next('/error'); // 加載失敗,重定向到錯誤頁}} else {next(); // 無需預加載,直接放行}
});
三、全局后置鉤子(afterEach
作用

路由跳轉完成后觸發,主要用于執行不需要干預導航的操作(如日志記錄、頁面滾動)。

觸發時機
  • 導航已完成,目標組件已渲染。
  • next 函數,無法攔截或修改導航
參數
  • to:成功進入的目標路由對象。
  • from:離開的路由對象。
示例(記錄訪問日志)
// 全局后置鉤子:記錄頁面訪問日志
router.afterEach((to, from) => {// 1. 打印跳轉信息console.log(`${from.path} 跳轉到 ${to.path}`);// 2. 調用接口記錄日志(實際項目中使用 axios 等工具)fetch('/api/log', {method: 'POST',body: JSON.stringify({fromPath: from.path,toPath: to.path,time: new Date().toISOString()})});// 3. 頁面滾動到頂部window.scrollTo(0, 0);
});
四、全局守衛的執行順序
  1. 觸發路由跳轉 → beforeEach(全局前置)
  2. 加載異步路由組件(若有)
  3. 執行目標路由的路由獨享守衛(beforeEnter
  4. 執行目標組件內的 beforeRouteEnter 守衛
  5. 所有異步操作完成 → beforeResolve(全局解析)
  6. 導航確認,組件渲染 → afterEach(全局后置)
五、核心使用場景
  • beforeEach:權限驗證、登錄攔截、動態路由生成。
  • beforeResolve:路由跳轉前的異步數據預處理。
  • afterEach:頁面訪問日志、滾動位置重置、埋點統計。
六、注意事項
  1. 避免無限循環:在 beforeEach 中重定向時,需確保條件判斷正確(如登錄頁不重定向自身)。
  2. 異步操作處理:若有異步邏輯(如接口請求),需用 async/await 包裹,并在完成后調用 next()
  3. 性能影響:全局守衛會攔截所有路由跳轉,復雜邏輯可能影響性能,建議保持簡潔。

全局守衛是 Vue Router 中實現統一導航控制的核心工具,通過合理組合三類守衛,可實現從權限驗證到數據處理的全流程管控。


2.2路由獨享守衛

可以為某個特定的路由配置守衛,只對該路由生效。

  • beforeEnter
    • 觸發時機:在進入對應的路由之前觸發。
    • 參數:接收三個參數,分別是to(即將要進入的目標路由對象)、from(當前導航正要離開的路由對象)、next(和全局守衛中的next 函數作用相同)。
    • 示例
const router = new VueRouter({routes: [{path: '/admin',component: Admin,beforeEnter: (to, from, next) => {// 只有管理員角色才能訪問const userRole = localStorage.getItem('role'); if (userRole === 'admin') {next();} else {next('/forbidden'); // 無權限則重定向到禁止訪問頁面}}}]
})

在 Vue Router 中,路由獨享守衛是一種僅作用于特定路由配置的導航鉤子,允許你在某個路由跳轉前進行定制化攔截和處理,而不必影響其他路由。以下是其核心用法與場景:

一、核心語法(beforeEnter
const router = new VueRouter({routes: [{path: '/admin',component: AdminPanel,beforeEnter: (to, from, next) => {// 路由獨享守衛邏輯if (!isAdmin) {next('/login'); // 無權限則重定向} else {next(); // 允許訪問}}}]
});
二、參數與執行流程
1. 參數
  • to:目標路由對象(包含路徑、參數、元信息等)。
  • from:當前路由對象。
  • next:控制導航行為的函數(同全局守衛的 next)。
2. 執行時機
  • 在全局前置守衛(beforeEach)之后,組件內守衛(beforeRouteEnter)之前執行。
  • 僅在進入該路由時觸發,離開時不觸發。
三、典型應用場景
1. 權限控制(如管理員頁面)
{path: '/admin',component: AdminPanel,beforeEnter: (to, from, next) => {const userRole = localStorage.getItem('role');if (userRole === 'admin') {next(); // 管理員允許訪問} else {next('/forbidden'); // 非管理員跳轉至禁止頁}}
}
2. 數據預處理
{path: '/profile/:id',component: UserProfile,beforeEnter: async (to, from, next) => {try {// 預加載用戶數據const user = await fetchUser(to.params.id);// 將數據存入路由元信息,供組件使用to.meta.user = user;next();} catch (error) {next('/404'); // 加載失敗跳轉 404}}
}
3. 導航條件判斷
{path: '/payment',component: PaymentPage,beforeEnter: (to, from, next) => {// 檢查購物車是否有商品const hasItems = localStorage.getItem('cartItems');if (hasItems) {next();} else {next('/cart'); // 無商品則跳轉購物車}}
}
四、與其他守衛的對比
守衛類型作用范圍觸發時機適用場景
全局前置守衛所有路由路由跳轉前統一權限驗證、登錄攔截
路由獨享守衛單個路由配置進入特定路由前特定頁面的權限控制、數據預加載
組件內守衛組件內部組件實例相關的導航階段組件級別的導航邏輯
五、注意事項
  1. 只作用于直接匹配的路由
    如果路由配置了子路由,beforeEnter 僅在進入該路由時觸發,不會作用于子路由。

  2. 避免重復邏輯
    若多個路由需要相同的守衛邏輯,建議使用全局守衛或高階函數封裝,減少代碼冗余。

  3. 異步操作處理
    若守衛中包含異步請求(如驗證 Token),需使用 async/await 確保數據加載完成后再調用 next()

六、總結

路由獨享守衛是 Vue Router 中實現細粒度導航控制的靈活工具,適合在不影響全局導航的前提下,對特定路由添加定制化的攔截邏輯。合理使用它可提升代碼的可維護性,避免全局守衛過于臃腫。


2.3組件內守衛

在路由組件內部定義的守衛,只在當前組件對應的路由跳轉時生效。

  • beforeRouteEnter
    • 觸發時機:在路由進入該組件之前觸發,此時組件實例還未被創建,所以不能訪問this
    • 參數:接收三個參數,分別是to(即將要進入的目標路由對象)、from(當前導航正要離開的路由對象)、nextnext 函數可以接收一個回調函數,在組件實例創建好之后執行 )。
    • 示例
export default {beforeRouteEnter(to, from, next) {// 模擬獲取數據后再進入組件getData().then(data => {next(vm => {vm.$data.data = data; // vm 是組件實例});}).catch(() => {next(false);});}
}
  • beforeRouteUpdate
    • 觸發時機:在當前路由改變,但是該組件被復用時調用,比如在帶有動態參數的路由中,當參數變化時,組件會被復用,此時會觸發該守衛。
    • 參數:接收三個參數,分別是to(即將要進入的目標路由對象)、from(當前導航正要離開的路由對象)、next(和其他守衛中的next 函數作用相同)。
    • 示例
export default {beforeRouteUpdate(to, from, next) {// 當路由參數變化時,重新獲取數據if (to.params.id!== from.params.id) {this.fetchNewData(to.params.id);}next();}
}
  • beforeRouteLeave
    • 觸發時機:在導航離開該組件時觸發,可用于詢問用戶是否確認離開,比如用戶在表單中輸入了內容還未保存時。
    • 參數:接收三個參數,分別是to(即將要進入的目標路由對象)、from(當前導航正要離開的路由對象)、next(和其他守衛中的next 函數作用相同)。
    • 示例
export default {beforeRouteLeave(to, from, next) {if (this.hasUnsavedChanges) {const confirmLeave = window.confirm('你有未保存的更改,確定要離開嗎?');if (confirmLeave) {next();} else {next(false);}} else {next();}}
}

通過合理運用這些路由守衛,可以實現豐富且強大的導航控制邏輯,提升應用的安全性和用戶體驗。

在 Vue Router 中,組件內守衛是直接定義在路由組件內部的導航鉤子,用于控制該組件實例相關的路由導航行為。與全局守衛和路由獨享守衛不同,組件內守衛僅作用于當前組件,提供更精細的導航控制。以下是其核心用法與場景:

一、三種組件內守衛
1. beforeRouteEnter
  • 觸發時機:在路由進入組件前觸發,此時組件實例尚未創建,因此無法訪問 this
  • 用途:可通過 next 回調訪問組件實例,常用于在路由進入前預加載數據。
  • 示例
    export default {beforeRouteEnter(to, from, next) {// 異步獲取數據(如用戶信息)fetchUser(to.params.id).then(user => {// 通過 next 回調訪問組件實例next(vm => {vm.user = user; // 將數據傳遞給組件實例});});}
    }
    
2. beforeRouteUpdate
  • 觸發時機:在當前路由改變(如參數變化)但組件被復用時觸發,此時組件實例已存在,可訪問 this
  • 用途:常用于動態參數路由(如 /user/:id)的更新邏輯,避免組件重復創建。
  • 示例
    export default {watch: {// 傳統方式:監聽 $route 變化$route(to) {this.fetchData(to.params.id);}},// 更優解:使用組件內守衛beforeRouteUpdate(to, from, next) {// 參數變化時重新加載數據if (to.params.id !== from.params.id) {this.fetchData(to.params.id);}next();}
    }
    
3. beforeRouteLeave
  • 觸發時機:在導航離開當前組件時觸發,可訪問 this
  • 用途:常用于阻止用戶意外離開(如未保存表單),或清理資源。
  • 示例
    export default {data() {return {formDirty: false // 表單是否已修改};},beforeRouteLeave(to, from, next) {if (this.formDirty) {const confirmLeave = window.confirm('表單尚未保存,確定離開?');confirmLeave ? next() : next(false); // 確認后允許離開} else {next(); // 未修改直接放行}}
    }
    
二、組件內守衛的執行順序

當路由發生變化時,守衛的觸發順序為:

  1. 全局beforeEach
  2. 路由獨享beforeEnter
  3. 組件內
    • 當前組件的 beforeRouteLeave(若離開當前組件)
    • 目標組件的 beforeRouteEnter(若進入新組件)
  4. 全局beforeResolve
  5. 全局afterEach
三、典型應用場景
1. 數據預加載
export default {beforeRouteEnter(to, from, next) {// 進入組件前預加載文章數據fetchArticle(to.params.id).then(article => {next(vm => {vm.article = article;});});}
}
2. 動態路由參數更新
export default {beforeRouteUpdate(to, from, next) {// 當路由參數變化時(如從 /user/1 到 /user/2)this.fetchUser(to.params.id);next();}
}
3. 防止數據丟失
export default {beforeRouteLeave(to, from, next) {// 檢查是否有未保存的草稿if (this.hasDraft) {saveDraft().then(() => next());} else {next();}}
}
四、與其他守衛的對比
守衛類型定義位置能否訪問 this適用場景
全局守衛路由配置文件全局權限驗證、日志記錄
路由獨享守衛路由配置對象特定路由的權限控制
組件內守衛組件內部beforeRouteEnter 不可,其他可組件級的導航邏輯、數據預加載
五、注意事項
  1. beforeRouteEnter 中訪問組件實例
    由于此時組件尚未創建,需通過 next(vm => { ... }) 回調訪問實例。

  2. 避免重復邏輯
    若多個組件需要相同的守衛邏輯,可使用 mixin 或全局守衛減少代碼冗余。

  3. 異步操作處理
    若守衛中包含異步請求(如驗證 Token),需確保數據加載完成后再調用 next()

六、總結

組件內守衛是 Vue Router 中實現組件級導航控制的強大工具,通過 beforeRouteEnterbeforeRouteUpdatebeforeRouteLeave 三個鉤子,可精確控制組件實例的導航生命周期。合理使用組件內守衛能提升用戶體驗(如防止數據丟失),并優化組件性能(如復用組件時的數據更新)。


3.history模式與hash模式

在 Vue Router 中,history 模式和**hash 模式**是兩種不同的路由實現方式,主要區別在于 URL 的表現形式和瀏覽器歷史記錄的處理方式。以下是詳細對比與選擇建議:

在這里插入圖片描述

一、核心區別
特性hash 模式(默認)history 模式
URL 格式http://example.com/#/homehttp://example.com/home
路徑標識符使用 # 符號分隔路徑(如 #/user/1直接使用真實路徑(如 /user/1
歷史記錄hash 變化會觸發瀏覽器歷史記錄,但不會向服務器發送請求依賴 HTML5 History API(pushState/replaceState),路徑變化會被記錄到歷史中
服務器配置無需特殊配置,所有請求都指向根頁面需要服務器配置,確保所有路由請求都返回同一個 HTML 文件
兼容性支持所有瀏覽器(包括 IE9+)依賴 HTML5 History API,IE9 及以下不支持
二、hash 模式詳解
  1. 工作原理
  • URL 中的 # 及其后的內容被視為瀏覽器的 hash 值,不會被發送到服務器。
  • hash 變化時(如 #/home#/about),Vue Router 會攔截并根據 hash 值渲染對應組件。
  1. 優點
  • 無需服務器配置:所有請求都指向根頁面(如 index.html),適合快速開發和靜態網站。
  • 兼容性強:支持所有現代瀏覽器,甚至包括 IE9。
  1. 缺點
  • URL 不美觀# 符號在 URL 中較為突兀,不符合傳統 URL 格式。
  • SEO 不友好:搜索引擎爬蟲通常會忽略 hash 值,不利于頁面收錄。
三、history 模式詳解
  1. 工作原理
  • 使用 HTML5 的 pushStatereplaceState API 操作瀏覽器歷史記錄,URL 看起來像傳統的靜態頁面路徑(如 /home)。
  • 當用戶訪問 /user/1 時,瀏覽器會向服務器發送請求,但實際上所有路徑都應返回同一個 HTML 文件(如 index.html),由 Vue Router 在客戶端處理路由邏輯。
  1. 優點
  • URL 更優雅:沒有 # 符號,符合傳統 URL 格式,提升用戶體驗。
  • SEO 友好:搜索引擎可以直接抓取真實路徑,有利于頁面收錄。
  1. 缺點
  • 服務器配置復雜:需要服務器配置所有路由請求都返回 index.html,否則會出現 404 錯誤(見下方服務器配置示例)。
  • 兼容性較差:不支持 IE9 及以下瀏覽器。
四、服務器配置示例(history 模式)
  1. Node.js (Express)
const express = require('express');
const app = express();// 靜態文件處理
app.use(express.static(__dirname + '/dist'));// 所有路由請求都返回 index.html
app.get('*', function(req, res) {res.sendFile(__dirname + '/dist/index.html');
});app.listen(8080);
五、如何選擇?
  • 優先使用 history 模式
    如果項目需要良好的 SEO、更優雅的 URL,且不考慮 IE9 及以下瀏覽器,推薦使用 history 模式。

  • 使用 hash 模式的場景

    • 項目不需要 SEO(如內部管理系統)。
    • 無法配置服務器(如 GitHub Pages、靜態網站托管)。
    • 需要兼容 IE9 及以下瀏覽器。
六、切換模式的方法

在 Vue Router 配置中,通過 mode 選項指定模式:

const router = new VueRouter({mode: 'history',  // 啟用 history 模式(默認是 hash 模式)routes: [...]
});
七、總結
場景hash 模式history 模式
靜態網站/快速開發??(需服務器配置)
企業內部系統?(兼容性好)?(URL 更優雅)
電商/內容網站(需 SEO)??
兼容性要求?(支持 IE9+)?(不支持 IE9 及以下)

選擇時需權衡 URL 美觀性、SEO 需求、服務器配置復雜度和瀏覽器兼容性。history 模式是現代 Web 應用的首選,但需要服務器配合;hash 模式則適用于快速迭代和兼容性要求高的場景。


(三)、vue-router(路由管理)

vue的一個插件庫,專門用來實現SPA應用

1.安裝與配置

使用npm install vue-router@3安裝,然后在項目中進行配置。
使用:Vue.use(Router);

// router/index.js
import Vue from 'vue';
import Router from 'vue-router';
import Home from '../views/Home.vue';
import About from '../views/About.vue';Vue.use(Router);export default new Router({// 路由模式,可選'hash'(默認,URL中包含#)和'history'(更美觀的URL)mode: 'history', routes: [{// 路由路徑path: '/', // 路由名稱name: 'Home', // 對應的組件component: Home },{path: '/about',name: 'About',component: About}]
});

main.js中引入并使用路由:

import Vue from 'vue';
import App from './App.vue';
import router from './router';new Vue({router,render: h => h(App)
}).$mount('#app');

2.路由導航與參數

  1. 導航:使用<router-link>組件進行路由導航。
<router-link to="/">Home</router-link>
<router-link to="/about">About</router-link>
  1. 動態路由參數:在路由路徑中使用參數,如/user/:id,可以在組件中通過$route.params獲取參數值。
// User.vue
export default {created() {const userId = this.$route.params.id;console.log('用戶ID:', userId);}
};

(四)對SPA應用的理解

  1. 定義:單頁 Web 應用(single page web application,SPA )
  2. 頁面特征:整個應用只有一個完整的頁面
  3. 交互特點:點擊頁面中的導航鏈接不會刷新頁面,只會做頁面的局部更新
  4. 數據獲取:數據需要通過 ajax 請求獲取

(五)基本路由

注意:

  1. 存儲位置
    • 路由組件:通常存放在 pages 文件夾
    • 一般組件:通常存放在 components 文件夾
  2. 路由組件銷毀與掛載:通過切換,“隱藏”了的路由組件,默認是被銷毀掉的,需要的時候再去掛載
  3. 組件路由信息屬性:每個組件都有自己的 $route 屬性,里面存儲著自己的路由信息
  4. 全局路由實例獲取:整個應用只有一個 router,可以通過組件的 $router 屬性獲取到 。

路由傳參

query參數(靜態)

在這里插入圖片描述
在這里插入圖片描述

命名路由
一、命名路由的作用

簡化路由跳轉:無需硬編碼完整路徑,通過路由名稱(name)實現跳轉,避免路徑變更時大量修改代碼。

二、使用步驟
1. 給路由“命名”(配置階段)

在路由配置中,為目標路由添加 name 屬性:

const routes = [{path: '/demo',component: Demo,children: [{path: 'test',component: Test,children: [{name: 'hello', // 給路由命名(關鍵)path: 'welcome',component: Hello}]}]}
]
2. 簡化跳轉(組件中使用)

未簡化前:需寫完整路徑,易出錯且難維護:

<router-link to="/demo/test/welcome">跳轉</router-link>

簡化后:通過 name 跳轉,路徑變化時只需改配置:

<router-link :to="{ name: 'hello' }">跳轉</router-link>

簡化寫法:命名路由 + query 參數

<!-- 簡化寫法:命名路由 + query 參數 -->
<router-link :to="{ name: 'hello', // 路由名稱(對應路由配置的 name: 'hello')query: {       // 傳遞 query 參數(會顯示在 URL 中,如 ?id=666&title=你好)id: 666, title: '你好' } }"
>跳轉并傳參
</router-link>
三、核心優勢
  • 解耦路徑與跳轉:路由名稱不變時,即使路徑(如 /demo/test/welcome)修改,跳轉代碼無需改動。
  • 支持動態參數:結合 params/query 傳參更靈活(如 :to="{ name: 'hello', params: { id: 1 } }" )。
總結

命名路由是給路由起一個“別名”(name),讓跳轉從“寫死路徑”變成“調用名稱”,核心價值是簡化跳轉邏輯、提升可維護性

路由的params參數(動態)
1.配置路由,聲明接收 params 參數

配置路由以接收 params 參數,通過 占位符(:id:title 定義動態路徑,讓組件能接收 URL
中的動態參數。

1.1. 路由配置(核心片段)
{path: '/home',component: Home,children: [{component: Message,children: [{name: 'xiangqing', path: 'detail/:id/:title', // 占位符聲明 params 參數component: Detail}]}]
}

代碼解析:

  • path: 'detail/:id/:title'
    • :id:title 占位符,聲明該路由需要接收 idtitle 兩個 params 參數。
    • 訪問時路徑如 /home/message/detail/1/xxx,其中 1xxx 會作為 params 傳遞。

流程說明 :

  1. 路由定義
    通過 path: 'detail/:id/:title' 告訴 Vue Router:

    • 該路徑是動態的,idtitle 是可變參數。
    • 這些參數會以 params 形式傳遞給 Detail 組件。
  2. 參數傳遞與接收

    • 跳轉時需通過 params 傳入數據(如 this.$router.push({ name: 'xiangqing', params: { id: 1, title: 'xxx' } }) )。
    • Detail 組件中通過 this.$route.params.idthis.$route.params.title 接收參數。

核心特點

  • 動態路徑:URL 中的 idtitle 是動態的,不同參數對應不同頁面狀態。
  • 強關聯路由params 參數必須與路由配置的占位符一一對應,否則路由無法匹配。
1.2對比 query 參數
對比項params 參數query 參數
路徑形式/detail/1/xxx(參數嵌入路徑)/detail?id=1&title=xxx(參數跟在 ? 后)
路由配置需用 :占位符 聲明無需特殊配置
參數是否必填是(否則路由不匹配)否(可傳可不傳)
1.3 注意事項
  1. 參數必填性
    由于 params 參數通過占位符聲明,跳轉時必須傳入對應參數,否則路由無法匹配(如少傳 title 會導致 404)。

  2. 命名路由配合
    建議結合 name: 'xiangqing' 使用,跳轉時代碼更簡潔:

    this.$router.push({ name: 'xiangqing', params: { id: 1, title: 'xxx' } 
    })
    
  3. 組件接收參數
    Detail 組件中,通過 this.$route.params 而非 props 接收(除非開啟 props: true 配置)。

這是 Vue Router 中 動態路由傳參 的基礎用法,核心是通過 占位符 讓 URL 攜帶動態數據,常用于商品詳情、文章詳情等場景~

2.params 參數的傳遞方式:
1. 字符串寫法(直接拼接路徑)
<!-- 跳轉并攜帶 params 參數(字符串拼接路徑) -->
<router-link to="/home/message/detail/666/你好">跳轉</router-link>
  • 特點
    • 直接拼接 params 到 URL(666id你好title)。
    • 需嚴格按照路由配置的 path: 'detail/:id/:title' 格式拼接,易出錯。
2. 對象寫法(推薦)
<!-- 跳轉并攜帶 params 參數(對象寫法) -->
<router-link :to="{ name: 'xiangqing', params: { id: 666, title: '你好' } }"
>跳轉
</router-link>
  • 關鍵規則
    • 必須用 name: 'xiangqing'(路由的命名),不能用 path
    • 通過 params 字段傳遞參數,Vue Router 會自動拼接成動態路徑。
注意事項

對象寫法的強制規則

  • 當用對象傳遞 params 時,必須通過 name 匹配路由,而不能用 path
  • 原因:path 是靜態的,無法動態拼接 paramsname 與路由配置的 name: 'xiangqing' 關聯,能正確解析 params
兩種寫法對比
寫法優點缺點適用場景
字符串寫法簡單直觀易因路徑變化(如參數順序)出錯簡單場景,參數少且固定
對象寫法解耦路徑與參數,更健壯需定義路由 name復雜場景,參數多或動態變化
核心結論

傳遞 params 參數時:

  • 若用 對象寫法,必須配合 name(不能用 path),這是 Vue Router 的強制規則。
  • 推薦優先用 對象寫法,避免路徑拼接錯誤,且更易維護(路由名稱不變時,路徑變化不影響跳轉)。

這是 Vue Router 中 params 參數傳遞的核心細節,記住 “對象寫法必須用 name” 即可避免常見錯誤~

3. 接收 params 參數:

在組件中獲取路由傳遞的 params 參數(如 idtitle),用于渲染動態內容(如商品詳情、文章標題)。

1.關鍵代碼
// 組件中接收 params 參數
const id = this.$route.params.id
const title = this.$route.params.title
2.流程說明
  1. 路由傳遞 params
    通過 router-linkthis.$router.push 傳遞 params(如 { params: { id: 666, title: '你好' } } )。

  2. 組件接收參數
    Vue Router 會將 params 掛載到 this.$route.params 中,組件直接訪問 this.$route.params.idthis.$route.params.title 即可。

3.與 query 參數的區別
參數類型存儲位置組件中獲取方式特點
params動態路徑(如 /detail/666/你好this.$route.params.xxx參數隱藏在路徑中,更“干凈”
queryURL 查詢字符串(如 ?id=666this.$route.query.xxx參數顯示在 URL 中,可分享
4.注意事項
  1. 路由配置依賴
    必須在路由中通過 path: 'detail/:id/:title' 聲明 params 占位符,否則 this.$route.params 無法獲取參數。

  2. 組件更新問題
    如果組件復用(如不同 id 但同一路由),需通過 watch 監聽 $route.params 變化:

    watch: {'$route.params'() {// 參數變化時重新加載數據this.fetchData(this.$route.params.id);}
    }
    
5.總結

接收 params 參數的核心是通過 this.$route.params.xxx,需注意路由配置的占位符聲明,以及組件復用場景下的參數監聽。這是 Vue Router 動態路由傳參的基礎用法,常用于商品詳情、文章詳情等場景。


路由的props配置

在 Vue Router 中,props 配置是一種將路由參數(如 paramsquery)直接映射為組件 props 的機制,目的是解耦組件與路由,讓組件更易于測試和復用。以下是其核心用法與場景:

一、基礎用法(三種模式)
1. 布爾模式(最常用)
  • 配置props: true
  • 效果:將 params 參數轉為組件 propsquery 不處理。
  • 示例
    // 路由配置
    {path: '/user/:id',component: User,props: true // 開啟 props 模式
    }// User 組件
    export default {props: ['id'], // 直接接收路由 params 參數mounted() {console.log(this.id); // 訪問路由參數}
    }
    
2. 對象模式
  • 配置props: { key: value }
  • 效果:傳遞固定的靜態數據給組件,不依賴路由參數。
  • 示例
    {path: '/about',component: About,props: { title: '關于我們', version: '1.0.0' } // 傳遞靜態數據
    }
    
3. 函數模式(最靈活)
  • 配置props: (route) => ({...})
  • 效果:通過函數動態生成 props,可處理 paramsquery 或其他邏輯。
  • 示例
    {path: '/search',component: Search,props: (route) => ({keyword: route.query.q, // 從 query 獲取參數page: parseInt(route.query.page) || 1 // 處理默認值})
    }
    

匯總:

{name:'xiangqing',path:'detail/:id',component:Detail,//第一種寫法:props值為對象,該對象中所有的key - value的組合最終都會通過props傳給Detail組件// props:{a:900}//第二種寫法:props值為布爾值,布爾值為true,則把路由收到的所有params參數通過props傳給Detail組件// props:true//第三種寫法:props值為函數,該函數返回的對象中每一組key - value都會通過props傳給Detail組件props(route){return {id:route.query.id,title:route.query.title}
二、核心優勢
  1. 組件復用性提升
    組件不再依賴 this.$route,可獨立使用(如在非路由場景下復用)。

    // 無 props 配置時,組件依賴路由
    console.log(this.$route.params.id); // 耦合路由// 有 props 配置時,組件只關心 props
    console.log(this.id); // 解耦路由,可獨立測試
    
  2. 測試更簡單
    測試組件時,可直接傳入 props,無需模擬路由環境。

    // 測試代碼示例
    const wrapper = shallowMount(User, {propsData: { id: '123' } // 直接傳入 props
    });
    
  3. 代碼更清晰
    組件 props 聲明明確,一眼看出依賴哪些參數。

三、對比直接訪問 $route
方式優點缺點適用場景
直接用 $route簡單直接,無需額外配置組件與路由強耦合小型項目、快速開發
props 配置解耦路由,組件可復用需要額外配置中大型項目、組件復用多
四、注意事項
  1. 僅處理 params
    props: true 時,只有 params 參數會被轉為 propsquery 參數需通過函數模式手動處理。

  2. 與命名路由配合
    傳遞 params 時,建議用命名路由(如 name: 'user'),避免路徑拼接錯誤。

    <router-link :to="{ name: 'user', params: { id: 1 } }">用戶詳情</router-link>
    
  3. 函數模式的性能
    函數模式每次路由變化都會執行,避免在函數中做復雜計算,可通過 computed 緩存結果。

五、典型場景
  • 商品詳情頁:通過 id 獲取商品數據。

    {path: '/product/:id',component: ProductDetail,props: true
    }
    
  • 搜索結果頁:通過 query 參數獲取搜索關鍵詞。

    {path: '/search',component: SearchResult,props: (route) => ({ keyword: route.query.q })
    }
    
  • 靜態頁面:傳遞固定數據(如標題、配置)。

    {path: '/help',component: HelpPage,props: { title: '幫助中心' }
    }
    
總結

props 配置是 Vue Router 中解耦組件與路由的關鍵機制,通過三種模式(布爾、對象、函數)將路由參數轉為組件 props,讓組件更獨立、可測試、易復用。建議在中大型項目中優先使用,提升代碼質量。

router-link的replace屬性

在 Vue Router 中,router-link 是用于生成導航鏈接的組件,它的 replace 屬性主要用于控制導航行為,以下是關于它的詳細介紹:
以下是提取的文字內容:

<router-link>replace屬性

  1. 作用:控制路由跳轉時操作瀏覽器歷史記錄的模式
  2. 瀏覽器的歷史記錄有兩種寫入方式:分別為pushreplacepush是追加歷史記錄,replace是替換當前記錄。路由跳轉時候默認為push
  3. 如何開啟replace模式:<router-link replace ……>News</router-link>
1. 基本作用

replace 屬性的作用是用新的歷史記錄條目替換當前的歷史記錄條目,而不是向歷史記錄棧中添加一個新條目。

在普通情況下,當我們使用 <router-link> 進行頁面跳轉時,每次跳轉都會在瀏覽器的歷史記錄中新增一條記錄,用戶可以通過點擊瀏覽器的“后退”按鈕回到上一個頁面。但是當給 <router-link> 添加了 replace 屬性后,跳轉時會替換當前的歷史記錄,此時瀏覽器的“后退”按鈕將無法退回到跳轉前的頁面 。

2. 使用方式

<router-link> 組件中,直接添加 replace 屬性即可,它不需要綁定具體的值,類似于 HTML 中的布爾屬性,只要存在該屬性,就會生效。示例代碼如下:

<template><div><!-- 普通的路由鏈接,會增加歷史記錄 --><router-link to="/home">前往首頁</router-link> <!-- 使用了replace屬性的路由鏈接,會替換歷史記錄 --><router-link to="/about" replace>前往關于頁面</router-link> </div>
</template>

上述代碼中,點擊“前往首頁”的鏈接時,瀏覽器歷史記錄會新增一條記錄;而點擊“前往關于頁面”的鏈接時,當前的歷史記錄會被替換。

3. 應用場景
  • 防止用戶返回:在一些場景下,比如用戶進行了不可逆的操作(如提交表單、支付成功后),不希望用戶通過點擊“后退”按鈕回到之前的頁面,此時可以使用 replace 屬性。例如,在電商網站中,當用戶完成支付后跳轉到支付成功頁面,為了避免用戶誤點“后退”按鈕回到支付頁面造成混亂,可以在支付成功頁面的跳轉鏈接中添加 replace 屬性。
<router-link to="/payment-success" replace>支付成功</router-link>
  • 簡化歷史記錄:當頁面的導航邏輯比較復雜,且某些跳轉不需要用戶回溯時,使用 replace 屬性可以讓瀏覽器的歷史記錄更加簡潔明了,避免歷史記錄中出現過多不必要的條目 。
4. 與編程式導航的對比

除了通過 <router-link>replace 屬性控制導航行為外,編程式導航(this.$router.pushthis.$router.replace)也能實現類似功能。

  • this.$router.push:向歷史記錄棧中添加一個新條目,與普通的 <router-link> 效果類似。
  • this.$router.replace:用新的條目替換當前歷史記錄條目,類似于 <router-link> 加上 replace 屬性。

示例代碼:

export default {methods: {goToPage() {// 普通push,增加歷史記錄this.$router.push('/some-page'); // 使用replace,替換歷史記錄this.$router.replace('/another-page'); }}
}

總之,router-linkreplace 屬性為我們在 Vue Router 中控制導航的歷史記錄行為提供了一種便捷的方式,合理使用它可以優化用戶體驗和頁面導航邏輯。

編程式路由導航

在 Vue Router 中,除了使用 <router-link> 聲明式創建導航鏈接外,還可以通過 編程式路由導航 實現更靈活的路由跳轉。這種方式通過 JavaScript 代碼觸發路由變化,適用于條件跳轉、事件回調等場景。

在這里插入圖片描述

一、核心 API
1. this.$router.push(location)
  • 作用:向歷史記錄棧中添加一個新條目,等同于 <router-link to>
  • 參數:可以是字符串路徑或描述目標位置的對象。
  • 示例
    // 字符串路徑
    this.$router.push('/home');// 對象路徑(命名路由 + params)
    this.$router.push({ name: 'user', params: { id: 123 } 
    });// 對象路徑(帶 query 參數)
    this.$router.push({ path: '/search', query: { keyword: 'vue' } 
    });
    
2. this.$router.replace(location)
  • 作用:替換當前歷史記錄條目,不創建新條目,等同于 <router-link replace>
  • 示例
    // 替換當前路由,禁止返回上一頁
    this.$router.replace('/login');
    
3. this.$router.go(n)
  • 作用:在歷史記錄中前進或后退,參數 n 為步數。
  • 示例
    this.$router.go(1); // 前進一頁(等同于 history.forward())
    this.$router.go(-1); // 后退一頁(等同于 history.back())
    this.$router.go(3); // 前進三頁
    
二、與 <router-link> 的對比
方式適用場景特點
<router-link>靜態導航鏈接(如導航欄、菜單)聲明式,簡單直觀
編程式路由導航動態邏輯跳轉(如按鈕點擊、條件判斷)靈活,可結合業務邏輯,支持異步操作
三、典型場景
1. 按鈕點擊跳轉
<template><button @click="handleLogin">登錄</button>
</template><script>
export default {methods: {handleLogin() {// 登錄邏輯...this.$router.push('/dashboard');}}
}
</script>
2. 條件跳轉
// 根據用戶權限跳轉
if (this.isAdmin) {this.$router.push('/admin');
} else {this.$router.push('/user');
}
3. 異步操作后跳轉
async fetchData() {await this.api.getUser();this.$router.replace('/profile'); // 替換路由,禁止返回
}
4. 帶參數跳轉
// 傳遞 params 參數
this.$router.push({ name: 'product', params: { id: this.selectedId } 
});// 傳遞 query 參數
this.$router.push({ path: '/search', query: { page: 2 } 
});
四、注意事項
  1. 路由鉤子與導航守衛
    編程式導航同樣會觸發全局導航守衛(如 beforeEach)和路由獨享守衛(如 beforeEnter),需注意邏輯順序。

  2. 命名路由優先
    傳遞動態參數(如 params)時,建議使用命名路由,避免路徑拼接錯誤。

  3. 錯誤處理
    導航失敗(如路由不存在)會返回一個被拒絕的 Promise,可以通過 .catch 捕獲錯誤:

    this.$router.push('/non-existent').catch(err => {console.error('導航失敗:', err);
    });
    
五、總結

編程式路由導航是 Vue Router 提供的 JavaScript 方式控制路由跳轉 的能力,通過 pushreplacego 等方法實現靈活的導航邏輯,適用于需要動態控制路由的場景。與 <router-link> 結合使用,能滿足各種復雜的路由需求。

緩存路由組件

在 Vue Router 中,緩存路由組件 是提升單頁應用性能和用戶體驗的重要手段,主要通過 <keep-alive> 組件實現。以下是核心機制與使用場景:

在這里插入圖片描述

一、核心原理
  • 普通組件行為:組件在切換時會被銷毀(beforeDestroy/destroyed),再次進入時重新創建(created/mounted)。
  • 緩存組件行為:使用 <keep-alive> 包裹的組件,在切換時不會被銷毀,而是進入“緩存狀態”(deactivated),再次進入時直接恢復(activated),避免重復渲染和數據請求。
二、基礎用法(??)
1. 全局緩存所有路由組件
<!-- App.vue -->
<router-view v-slot="{ Component }"><keep-alive><component :is="Component" /></keep-alive>
</router-view>
2. 緩存特定組件(推薦)

通過 include/exclude 指定緩存組件名稱(組件的 name 選項):

<!-- 只緩存 Home 和 User 組件 -->
<keep-alive include="Home,User">//include:組件名<router-view />
</keep-alive><!-- 排除 Login 組件 -->
<keep-alive exclude="Login"><router-view />
</keep-alive>
3. 動態緩存(通過路由元信息)

在路由配置中添加 meta.keepAlive,動態控制是否緩存:

// router.js
const routes = [{path: '/home',component: Home,meta: { keepAlive: true } // 需要緩存},{path: '/detail',component: Detail,meta: { keepAlive: false } // 不需要緩存}
];
<!-- App.vue -->
<router-view v-slot="{ Component }"><keep-alive><component :is="Component" v-if="$route.meta.keepAlive" /></keep-alive><component :is="Component" v-if="!$route.meta.keepAlive" />
</router-view>
語法與作用說明

在 Vue 中,<keep-alive> 組件的 include 屬性用于指定需要緩存的組件名稱,值可以是字符串、正則表達式,也可以是數組(數組里放組件名稱字符串) 。你代碼里的寫法:

<keep-alive :include="['News','Message']">  
<router-view></router-view> </keep-alive>

表示:僅緩存名稱為 NewsMessage 的組件,當這兩個組件在 <router-view>
中切換時,會被緩存(組件實例不會銷毀,再次進入時不會重新執行創建階段的鉤子,而是觸發 activated 等緩存相關鉤子 ),其他未匹配名稱的組件則不會被緩存。

關鍵前提條件

  1. 組件需有 name 選項NewsMessage 組件必須在自身定義中顯式聲明 name,且名稱要和 include 里的字符串嚴格一致,
    示例:
// News.vue export default
{   name: 'News', // 必須聲明,且和 include 里的 'News' 一致   // ... }// Message.vue export default {   name: 'Message',    // ... }

如果是單文件組件未手動寫 name,Vue 會默認將文件名作為 name(比如 News.vue 會默認 name: 'News' ),但為了清晰和避免意外,建議手動聲明。

  1. 配合路由使用場景: 這種寫法通常用于在路由切換時,緩存特定的頁面級組件(即通過 router-view 渲染的組件 )。比如 NewsMessage 是兩個路由組件,通過路由配置映射到不同路徑,當在這兩個路由間切換時,就能利用
    keep-alive 緩存它們的狀態。

常見擴展用法對比

  • 字符串形式include="News" ,只能緩存一個組件,適合單一目標場景。
  • 正則形式:include="/News|Message/"(需結合 v-bind 綁定,因為是 JavaScript 表達式 ),用正則匹配組件名稱,靈活但相對難維護。
  • 數組形式(你代碼里的寫法)::include="['News','Message']" ,清晰列出要緩存的組件,適合明確知道緩存范圍的場景,也是實際項目里常用的方式。

只要滿足上述組件 name 匹配等條件,你的寫法是合法且推薦的,能精準控制緩存范圍,避免不必要的組件緩存,節省內存、提升性能。

核心區別:靜態字符串 vs 動態綁定數組
寫法語法類型解析方式
include="Home,User,Product"靜態字符串Vue 會直接將字符串按逗號分割為數組 ['Home', 'User', 'Product']
:include="['Home','User']"動態綁定 JavaScript 數組通過 v-bind 綁定 JS 表達式,需在 Vue 實例中定義或直接寫數組字面量
三、緩存組件的生命周期鉤子
  • activated:組件被激活時觸發(首次加載或從緩存中恢復)。
  • deactivated:組件被緩存時觸發(離開但不銷毀)。

典型應用:在 activated 中判斷是否需要重新加載數據:

export default {data() {return {data: null,loaded: false};},activated() {if (!this.loaded) {this.fetchData(); // 只在首次加載或數據過期時請求this.loaded = true;}},methods: {fetchData() {// API 請求...}}
};
四、適用場景
  1. 頻繁切換的頁面:如標簽頁(Tab),避免每次切換都重新渲染。
  2. 數據加載耗時的頁面:如商品詳情頁,緩存后二次訪問無需重新請求數據。
  3. 需要保存狀態的表單:如多步驟表單,切換步驟時保留已填寫內容。
五、注意事項
  1. 內存占用:過多緩存組件會增加內存開銷,建議僅緩存關鍵頁面。
  2. 數據更新:緩存組件不會觸發 mounted,需在 activated 中處理數據更新。
  3. 組件復用問題:動態路由(如 /user/:id)切換不同參數時,組件會復用而不觸發 activated,需通過 watch 監聽 $route 變化:
    watch: {$route() {this.fetchData(); // 路由參數變化時重新加載}
    }
    
六、高級用法
1. 結合 max 屬性限制緩存數量
<keep-alive max="3"> <!-- 最多緩存 3 個組件 --><router-view />
</keep-alive>
2. 動態控制緩存狀態

通過修改路由元信息或組件 name,在運行時動態決定是否緩存:

// 導航守衛中動態設置
router.beforeEach((to, from, next) => {if (to.name === 'Detail' && from.name === 'List') {to.meta.keepAlive = true; // 從列表頁進入詳情頁時緩存}next();
});
七、總結

緩存路由組件是優化 SPA 性能的重要手段,通過 <keep-alive> 實現組件復用,避免重復渲染和數據請求。合理使用 include/exclude、路由元信息及生命周期鉤子,能在提升體驗的同時避免內存問題。

案例

以下是關于 Vue Router 核心特性的綜合解析,通過 電商商品詳情頁 案例串聯所有知識點:

案例場景

假設你正在開發一個電商網站,需要實現以下功能:

  • 從商品列表頁點擊商品,跳轉到詳情頁(攜帶商品 ID)。
  • 詳情頁包含 基本信息用戶評價相關推薦 三個子頁面(嵌套路由)。
  • 評價頁支持按時間/評分篩選(query 參數)。
  • 商品詳情頁需要緩存,避免重復加載數據。
1. 路由配置(router.js
const routes = [// 商品列表頁{ path: '/products', component: ProductsList },// 商品詳情頁(動態路由 + 嵌套路由){path: '/product/:id', // params 參數:商品 IDname: 'ProductDetail', // 命名路由component: ProductDetail,props: true, // 啟用 props 接收 paramschildren: [{ path: '', redirect: 'info' }, // 默認子路由{ path: 'info', component: ProductInfo },{ path: 'reviews', component: ProductReviews },{ path: 'related', component: RelatedProducts }]}
];
2. 路由傳參與導航
(1)query 參數(篩選條件)
<!-- 商品評價頁:篩選按鈕 -->
<router-link :to="{ name: 'ProductDetail', params: { id: productId }, query: { sort: 'time' } }"
>按時間排序
</router-link><!-- 在組件中獲取 query 參數 -->
export default {computed: {sortType() {return this.$route.query.sort || 'default';}}
}
(2)命名路由 + params 參數(商品 ID)
<!-- 商品列表項:跳轉到詳情頁 -->
<router-link :to="{ name: 'ProductDetail', params: { id: item.id } }"
>{{ item.name }}
</router-link><!-- 編程式導航(按鈕點擊) -->
methods: {goToDetail() {this.$router.push({name: 'ProductDetail',params: { id: this.selectedId }});}
}
(3)路由的 props 配置(簡化參數接收)
// 路由配置
{path: '/product/:id',component: ProductDetail,props: true // 將 params 轉為組件 props
}// 在 ProductDetail 組件中直接接收
export default {props: ['id'],mounted() {this.fetchProductData(this.id);}
}
3. router-link 的 replace 屬性
<!-- 使用 replace 替換當前歷史記錄,禁止后退 -->
<router-link :to="{ name: 'ProductDetail', params: { id } }"replace
>立即購買
</router-link>
4. 緩存路由組件(keep-alive
<!-- App.vue:緩存商品詳情頁 -->
<router-view v-slot="{ Component }"><keep-alive include="ProductDetail"><component :is="Component" /></keep-alive>
</router-view><!-- 被緩存組件的生命周期鉤子 -->
export default {activated() {// 組件被激活時觸發(緩存后首次加載或重新顯示)if (!this.$route.meta.loaded) {this.fetchData(); // 只在首次加載時請求數據this.$route.meta.loaded = true;}},deactivated() {// 組件被緩存時觸發(隱藏但不銷毀)}
}
5. 完整流程圖
商品列表頁(/products)└── 點擊商品(攜帶 id 參數)↓
商品詳情頁(/product/123)├── 默認顯示:基本信息(/product/123/info)├── 切換到評價頁(/product/123/reviews?sort=time)│     └── query 參數控制篩選邏輯└── 切換到相關推薦(/product/123/related)[緩存機制]
當從詳情頁跳轉到其他頁面時,詳情頁組件不會銷毀,
再次返回時直接顯示緩存內容,無需重新加載數據。
核心知識點總結
特性作用示例
query 參數用于傳遞可選參數(如篩選條件),顯示在 URL 中(?sort=time)。<router-link :to="{ query: { sort: 'time' } }">
命名路由為路由定義名稱,避免硬編碼路徑,提高可維護性。name: 'ProductDetail' + this.$router.push({ name: '...' })
params 參數用于傳遞必需參數(如 ID),通過動態路由(:id)接收。path: '/product/:id' + this.$route.params.id
props 配置將 params 轉為組件 props,解耦組件與路由。props: true + export default { props: ['id'] }
replace 屬性替換當前歷史記錄,禁止返回上一頁。<router-link replace>
緩存路由組件使用 keep-alive 緩存組件狀態,避免重復渲染。<keep-alive include="ProductDetail"> + activated() 生命周期鉤子
兩個新的生命周期鉤子
  1. ** 作用**:路由組件所獨有的兩個鉤子,用于捕獲路由組件的激活狀態。
  2. 具體名字
    1. activated 路由組件被激活時觸發。
    2. deactivated 路由組件失活時觸發。在這里插入圖片描述

Vue UI組件庫

一、移動端組件庫

庫名特點技術棧官網地址適用場景
Vant有贊出品,更新活躍,組件全Vue 2/3https://vant-contrib.gitee.io/vant/電商、表單、中大型項目
NutUI京東出品,輕量高效Vue 2/3https://nutui.jd.com/快速迭代項目
Cube UI滴滴開源,定制性強Vue 2https://didi.github.io/cube-ui/需深度定制的移動端項目
Mint UI經典老庫(維護停滯)Vue 2https://github.com/ElemeFE/mint-ui舊項目維護(慎用于新項目)

二、PC 端組件庫

庫名特點技術棧官網地址適用場景
Element UI元老級,文檔完善Vue 2https://element.eleme.cn/企業后臺、管理系統
Element PlusElement 官方 Vue 3 版本Vue 3https://element-plus.org/新項目(Vue 3 技術棧)
View UI原 iView,設計現代Vue 2/3https://www.iviewui.com/中后臺系統、數據可視化
Ant Design Vue阿里系,組件豐富Vue 2/3https://www.antdv.com/復雜業務系統、中臺產品

三、跨端/全場景組件庫

庫名特點技術棧官網地址適用場景
Naive UI全場景,性能優異Vue 3https://www.naiveui.com/中大型 Web 應用(Vue 3)
Arco Design字節跳動出品,設計統一Vue 2/3https://arco.design/vue企業級產品、多端一致性需求

在這里插入圖片描述

四、使用建議

  1. 技術棧匹配

    • Vue 2:選 Element UI、Vant、View UI
    • Vue 3:選 Element Plus、Naive UI、Ant Design Vue
  2. 場景選擇

    • 電商/移動端:Vant(功能最全)
    • 企業后臺:Element UI/Plus(穩定)或 Ant Design Vue(組件豐富)
    • 快速開發:NutUI(體積小)或 View UI(設計現代)
  3. 避坑指南

    • 避免在新項目中使用 Mint UI(已停止維護)
    • 注意組件庫與 Vue 版本的兼容性
    • 按需引入組件以減小打包體積(參考各庫文檔)

五、快速上手示例(Vant)

# 安裝
npm i vant@next -S  # Vue 3 項目
npm i vant -S       # Vue 2 項目# 按需引入(推薦)
npm i unplugin-vue-components unplugin-auto-import -D
// vite.config.js
import { defineConfig } from 'vite'
import AutoImport from 'unplugin-auto-import/vite'
import Components from 'unplugin-vue-components/vite'
import { VantResolver } from 'unplugin-vue-components/resolvers'export default defineConfig({plugins: [AutoImport({resolvers: [VantResolver()],}),Components({resolvers: [VantResolver()],}),],
})

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

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

相關文章

在 Windows 上安裝設置 MongoDB及常見問題

介紹 MongoDB 是一個開源的 NoSQL 數據庫系統&#xff0c;它以一種靈活的類似 JSON 的格式&#xff08;稱為 BSON&#xff08;二進制 JSON&#xff09;&#xff09;存儲數據。它使用動態模式&#xff0c;這意味著與關系型數據庫不同&#xff0c;MongoDB 不需要在向數據庫添加數…

Effective C++ 條款01:視 C++ 為一個語言聯邦

Effective C 條款01&#xff1a;視 C 為一個語言聯邦核心思想&#xff1a;C 是由多個子語言組成的聯邦&#xff0c;每個子語言有自己的編程范式。理解這些子語言及其規則切換&#xff0c;是寫出高效 C 代碼的關鍵。 四個子語言及其規則&#xff1a; C 語言 基礎&#xff1a;過程…

云效CI/CD教程(PHP項目)

參考文檔 參考云效的官方文檔https://help.aliyun.com/zh/yunxiao/ 一、新建代碼庫 這是第一步&#xff0c;和碼云的差不多 二、配SSH密鑰 這個和碼云&#xff0c;github上類似&#xff0c;都需要&#xff0c;云效的SSH密鑰證書不是采用 RSA算法&#xff0c;而是采用了ED2…

單片機是怎么控制的

單片機作為電子系統的控制核心&#xff0c;通過接收外部信號、執行預設程序、驅動外部設備的方式實現控制功能&#xff0c;其控制過程涉及信號輸入、數據處理和指令輸出三個關鍵環節&#xff0c;每個環節的協同配合決定了整體控制效果。 信號輸入&#xff1a;獲取外部信息 單片…

deepseek本地部署,輕松實現編程自由

小伙伴們&#xff0c;大家好&#xff0c;今天我們來實現deepseek本地部署&#xff0c;輕松實現編程自由&#xff01;安裝ollama 安裝ollama 首先我們安裝ollama 打開ollama官網&#xff0c;下載安裝符合自己系統的版本。 找到要安裝的模型deepseek-r1開始-運行 輸入cmd出現…

基礎NLP | 常用工具

編輯器 PycharmVSCodeSpyderPython 自帶 ideVim 機器學習相關python框架 Pytorch 學術界寵兒&#xff0c;調試方便&#xff0c;目前的主流Tensorflow 大名鼎鼎&#xff0c;工程配套完善Keras 高級封裝&#xff0c;簡單好用&#xff0c;現已和Tensorflow合體Gensim 訓練詞向…

Unity3D + VR頭顯 × RTSP|RTMP播放器:構建沉浸式遠程診療系統的技術實踐

一、背景&#xff1a;遠程醫療邁入“沉浸式協同”的新階段 過去&#xff0c;遠程醫療主要依賴視頻會議系統&#xff0c;實現基礎的遠程問診、會診或術中指導。雖然初步解決了地域限制問題&#xff0c;但其單視角、平面化、缺乏沉浸感與交互性的特征&#xff0c;已無法滿足臨床…

海云安斬獲“智能金融創新應用“標桿案例 彰顯AI安全左移技術創新實力

近日&#xff0c;由中國人民銀行廣東省分行、廣東省金融管理局、廣東省政務服務和數據管理局指導&#xff0c;廣東省金融科技協會主辦的“智能金融 創新應用”優秀案例名單最終揭曉&#xff0c;海云安開發者安全助手系統項目憑借其創新的"AI安全左移"技術架構&#x…

Fluent許可與網絡安全策略

在流體動力學模擬領域&#xff0c;Fluent軟件因其卓越的性能和廣泛的應用而備受用戶青睞。然而&#xff0c;隨著網絡安全威脅的不斷增加&#xff0c;確保Fluent許可的安全性和合規性變得尤為重要。本文將探討Fluent許可與網絡安全策略的關系&#xff0c;為您提供一套有效的安全…

如何借助AI工具?打贏通信設備制造的高風險之戰?(案例分享)

你是否曾在項目管理中遇到過那種讓人心跳加速的瞬間&#xff0c;當一項風險突然暴露出來時&#xff0c;全隊似乎都屏住了呼吸&#xff1f;今天&#xff0c;我就來分享一個我親歷的項目案例&#xff0c;講述我們如何借助具體的AI工具&#xff0c;實現從數據到決策的華麗轉變&…

Web服務器(Tomcat、項目部署)

1. 簡介 1.1 什么是Web服務器 Web服務器是一個應用程序&#xff08;軟件&#xff09;&#xff0c;對HTTP協議的操作進行封裝&#xff0c;使得程序員不必直接對協議進行操作&#xff0c;讓Web開發更加便捷。主要功能是"提供網上信息瀏覽服務"。 Web服務器是安裝在服…

list 介紹 及 底層

list的相關文檔&#xff1a;list - C Reference 一、list的介紹及使用 list中的接口比較多&#xff0c;此處類似&#xff0c;只需要掌握如何正確的使用&#xff0c;然后再去深入研究背后的原理&#xff0c;已達到可擴展的能力。以下為list中一些常見的重要接口。我們庫里的list…

HCIP MGRE實驗

一、實驗要求 1、R5為ISP&#xff0c;只能進行IP地址配置&#xff0c;其所有地址均配為公有Ip地址; 2、 R1和R5間使用PPP的PAP認證&#xff0c;R5為主認證方&#xff1b; R2與R5之間使用PPP的CHAP認證&#xff0c;R5為主認證方; R3與R5之間使用HDLC封裝; 3、R2、R3構建一…

基于PyTorch的多視角二維流場切片三維流場預測模型

基于PyTorch的多視角二維流場切片三維流場預測模型 前些天發現了一個巨牛的人工智能學習網站&#xff0c;通俗易懂&#xff0c;風趣幽默&#xff0c;忍不住分享一下給大家&#xff0c;覺得好請收藏。點擊跳轉到網站。 1. 引言 計算流體動力學(CFD)在工程設計和科學研究中扮演…

全新輕量化PHP網盤搜索引擎系統源碼

內容目錄一、詳細介紹二、效果展示1.部分代碼2.效果圖展示三、學習資料下載一、詳細介紹 全新輕量化PHP網盤搜索引擎系統源碼 基于PHPMYSQL開發 一、多樣篩選功能&#xff1a;網站支持5類篩選功能&#xff0c;包括默認搜索、網盤類型、文件大小、時間排序以及網盤來源&#x…

C study notes[3]

文章目錄operatonsloopsreferencesoperatons the fundamental operators such as ,-,* in C language can be simply manipulated. int sum 5 3; // sum 8 int difference 10 - 4; // difference 6 int product 6 * 7; // product 42the operator / was left to in…

練習實踐-基礎設施-文件共享-windows和linux之間的文件共享-smb服務搭建

參考來源&#xff1a; 在線書籍-linux就該這么學-第12章 安裝軟件包 配置文件/etc/samba/smb.conf 運維對待配置文件的態度&#xff0c;非必要不增加 安裝完畢后打開Samba服務程序的主配置文件&#xff0c;好在參數并不多&#xff0c;只有37行。其中第17&#xff5e;22行代…

常用設計模式系列(十三)—組合模式

常用設計模式系列&#xff08;十三&#xff09;—組合模式 第一節 前言 hello大家好&#xff0c;今年已經過去了一半&#xff0c;年初立下的flag&#xff0c;不知道實現了沒有&#xff0c;你的flag改了多少次&#xff1f;無論自己的愿望是否完成&#xff0c;我們都應該懷揣著追…

字節碼操作工具——ByteBuddy應用(3)安全檢查

一、檢測方法名是否符合規范1、代碼&#xff08;1&#xff09;MethodLoggerAgentpackage com.example.agent;import net.bytebuddy.agent.builder.AgentBuilder; import net.bytebuddy.asm.Advice; import net.bytebuddy.matcher.ElementMatchers;import java.lang.instrument.…

NineData 數據庫 DevOps 全面支持 GaussDB,國產化管理再升級!

NineData 數據庫 DevOps 平臺現已全面兼容 GaussDB 全線產品&#xff08;包括 GaussDB 企業級、DWS 數據倉庫、openGauss 開源版&#xff09;&#xff0c;實現一站式管理。無論 GaussDB 實例部署在哪個環境&#xff0c;企業所有開發者都可以通過 NineData 統一訪問&#xff0c;…