Vue Router 4與路由管理實戰

Amd794發表於2024-06-07

title: Vue Router 4與路由管理實戰
date: 2024/6/7
updated: 2024/6/7

excerpt:
這篇文章介紹瞭如何在Vue.js應用中利用Vue Router實現單頁面應用的路由管理,包括配置路由、導航守衛的使用、路由懶載入以最佳化效能以及動態路由的實現方法,旨在提升使用者體驗和應用載入效率

categories:

  • 前端開發

tags:

  • Vue Router
  • 單頁面應用
  • 路由管理
  • 導航守衛
  • 路由懶載入
  • 程式碼分割
  • 動態路由

image

第1章 Vue Router簡介

1.1 Vue Router的概念與作用

Vue Router 是 Vue.js 的官方路由管理器,它用於構建單頁面應用程式(Single Page Application,SPA)。在單頁面應用中,頁面不會重新載入,而是透過非同步請求來更新頁面內容。Vue Router 允許我們透過定義路由規則來實現不同頁面元件的切換,它提供了一種簡潔的、宣告式的路由方式,使得頁面之間的導航變得簡單直觀。

Vue Router 的主要作用包括:

  • 維護應用的狀態,即當前處於哪個路由。
  • 為應用提供路由檢視,即顯示當前路由對應的元件。
  • 管理路由之間的切換,包括頁面跳轉、資料載入等。
  • 提供路由守衛,用於在路由切換過程中執行程式碼,例如許可權驗證、頁面訪問日誌記錄等。

1.2 Vue Router的發展歷程

Vue Router 的發展可以分為幾個階段:

  • 早期版本:Vue Router 最初是作為 Vue.js 的一個外掛出現的,它為 Vue.js 提供了路由功能。
  • Vue Router 2.x:隨著 Vue.js 的發展,Vue Router 也在 2016 年釋出了 2.0 版本,這個版本支援 Vue 2.x,並引入了許多新特性和改進。
  • Vue Router 3.x:在 Vue 3 釋出之前,Vue Router 3.x 版本進行了大量的最佳化和改進,包括更好的型別支援、非同步元件等。
  • Vue Router 4:隨著 Vue 3 的釋出,Vue Router 4 也隨之而來,它完全相容 Vue 3,並帶來了一些重要的新特性和效能最佳化。cmdragon's Blog

1.3 Vue Router 4的新特性

Vue Router 4 帶來了以下新特性:

  • 相容 Vue 3:Vue Router 4 專為 Vue 3 設計,與 Vue 3 的組合式 API 完全相容。
  • 更簡潔的 API:Vue Router 4 簡化了一些 API,使得路由的配置和使用更加直觀。
  • 更好的型別支援:Vue Router 4 提供了更好的 TypeScript 支援,使得型別檢查更加嚴格和可靠。
  • 巢狀路由的改進:Vue Router 4 對巢狀路由進行了最佳化,使得巢狀路由的配置更加靈活。
  • 路由懶載入:Vue Router 4 支援路由懶載入,有助於提高應用的載入速度和效能。
  • 更強大的路由守衛:Vue Router 4 提供了更細粒度的路由守衛,使得路由控制更加靈活。

第2章 Vue Router 4的安裝與配置

2.1 環境搭建

在開始使用 Vue Router 4 之前,需要確保已經安裝了 Node.js 和 npm。然後可以使用 Vue CLI 來建立一個新的 Vue 3 專案,Vue CLI 會自動安裝 Vue Router 4。

npm install -g @vue/cli
vue create my-vue-router-project

2.2 安裝Vue Router 4

在建立好的專案中,可以使用 npm 或 yarn 來安裝 Vue Router 4。

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

2.3 配置路由表

在 Vue 3 專案中,通常會在 src/router 目錄下建立一個 index.js 檔案來配置路由表。

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;

2.4 路由的懶載入

路由懶載入可以幫助我們將不同路由對應的元件分割成不同的程式碼塊,從而提高應用的載入速度。在 Vue Router 4 中,可以使用動態匯入(Dynamic Imports)來實現路由的懶載入。
AD:等你探索

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

第3章 路由的基本使用

3.1 定義路由

定義路由就是建立一個路由表,它由一組路由規則組成,每個規則都定義了一個路徑和對應的元件。

const routes = [
  { path: '/', component: Home },
  { path: '/about', component: About }
];

3.2 路由的跳轉與導航

使用 <router-link> 元件進行宣告式導航:

<template>
  <router-link to="/">Home</router-link>
  <router-link to="/about">About</router-link>
</template>

使用 router.push 方法進行程式設計式導航:

// 在 Vue 元件的 methods 中
methods: {
  navigateToAbout() {
    this.$router.push('/about');
  }
}

3.3 動態路由匹配

動態路由允許我們在路由路徑中定義引數部分,從而使得一個路由可以匹配多個路徑。動態片段用 : 來標識。

const routes = [
  // 動態路徑引數以冒號 `:` 開頭
  { path: '/user/:userId', component: User }
];

在元件中可以透過 $route.params 訪問這些引數:

export default {
  computed: {
    userId() {
      return this.$route.params.userId;
    }
  }
}

3.4 路由的巢狀

Vue Router 允許我們巢狀路由,這意味著你可以在路由中定義路由,實現元件的巢狀顯示。

const routes = [
  {
    path: '/user/:userId',
    component: User,
    children: [
      // 當 /user/:userId 匹配成功後,會渲染 User 元件,
      // User 元件內部會渲染巢狀的 <router-view>,顯示 UserPosts
      {
        path: 'posts',
        component: UserPosts
      },
      // ...其他子路由
    ]
  }
];

User 元件內部,你可以使用 <router-view> 來顯示子路由匹配到的元件:

<template>
  <div>
    <h2>User {{ userId }}</h2>
    <router-view></router-view> <!-- 子路由匹配到的元件將在這裡渲染 -->
  </div>
</template>

第4章 路由的導航守衛

4.1 導航守衛的概念

導航守衛是 Vue Router 提供的一種機制,用於在路由發生改變時執行一些邏輯,如許可權驗證、日誌記錄等。導航守衛可以控制路由是否允許跳轉,以及在跳轉前後執行特定的操作。
AD:享受無干擾的沉浸式閱讀之旅

4.2 全域性守衛

全域性守衛作用於整個應用的所有路由。Vue Router 提供了三種全域性守衛:

  • router.beforeEach:全域性前置守衛,在路由切換前被呼叫。
  • router.beforeResolve:全域性解析守衛,在導航被確認前,所有元件內守衛和非同步路由元件被解析之後呼叫。
  • router.afterEach:全域性後置守衛,在路由切換後被呼叫。
// 註冊一個全域性前置守衛
router.beforeEach((to, from, next) => {
  // to 和 from 都是路由資訊物件
  // next 是一個函式,必須呼叫它來 resolve 這個鉤子
  next(); // 確保一定要呼叫 next()
});

4.3 路由獨享守衛

路由獨享守衛是在路由配置上直接定義的守衛,只作用於當前路由或巢狀路由。

const routes = [
  {
    path: '/foo',
    component: Foo,
    beforeEnter: (to, from, next) => {
      // 在進入路由前執行的邏輯
      next();
    }
  }
];

4.4 元件內守衛

元件內守衛是在元件內部定義的守衛,包括:

  • beforeRouteEnter:在路由進入前呼叫,此時元件例項還未建立。
  • beforeRouteUpdate:在當前路由改變,但是該元件被複用時呼叫。
  • beforeRouteLeave:在離開當前路由時呼叫。
export default {
  beforeRouteEnter(to, from, next) {
    // 在渲染該元件的對應路由被 confirm 前呼叫
    // 不!能!獲取元件例項 `this`
    // 因為當守衛執行前,元件例項還沒被建立
    next();
  },
  beforeRouteUpdate(to, from, next) {
    // 在當前路由改變,但是該元件被複用時呼叫
    // 舉例來說,對於 /foo/bar 路由來說,當 /foo/baz 導航時,
    // 由於兩個路由都渲染同一個 Foo 元件,因此這個守衛會被呼叫
    next();
  },
  beforeRouteLeave(to, from, next) {
    // 導航離開該元件的對應路由時呼叫
    // 可以訪問元件例項 `this`
    next();
  }
}

第5章 路由的懶載入與程式碼分割

5.1 路由懶載入的概念

路由懶載入是一種最佳化技術,它允許我們在需要時才載入路由對應的元件,而不是在應用初始化時就載入所有元件。這可以減少初始載入時間,提高應用效能。
AD:覆蓋廣泛主題工具可供使用

5.2 使用 import 語句實現懶載入

const Foo = () => import('./Foo.vue');

const routes = [
  { path: '/foo', component: Foo }
];

5.3 使用動態 import 語法實現懶載入

const routes = [
  {
    path: '/bar',
    component: () => import(/* webpackChunkName: "group-bar" */ './Bar.vue')
  }
];

5.4 程式碼分割與最佳化

程式碼分割是一種將程式碼庫分割成小塊的技術,這些小塊可以在需要時按需載入。這通常透過 Webpack 等打包工具實現,可以顯著提高應用的載入速度和效能。

第6章 路由的引數傳遞與資料獲取

6.1 路由引數的傳遞方式

路由引數可以透過路由路徑、查詢引數或路由元資訊傳遞。

6.2 路由的 query 引數

查詢引數是透過 URL 的查詢字串傳遞的引數,可以透過 $route.query 訪問。

const routes = [
  { path: '/search', component: Search }
];

在元件中訪問:

export default {
  computed: {
    query() {
      return this.$route.query;
    }
  }
}

6.3 路由的 params 引數

路徑引數是透過路由路徑中的動態片段傳遞的引數,可以透過 $route.params 訪問。

const routes = [
  { path: '/user/:id', component: User }
];

在元件中訪問:

export default {
  computed: {
    userId() {
      return this.$route.params.id;
    }
  }
}

6.4 路由的 meta 欄位

路由元資訊是在路由配置中定義的額外資訊,可以透過 $route.meta 訪問。

const routes = [
  {
    path: '/foo',
    component: Foo,
    meta: { requiresAuth: true }
  }
];

在守衛中訪問:

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !isAuthenticated) {
    next('/login');
  } else {
    next();
  }
});

6.5 資料獲取與路由守衛的結合

在路由守衛中,我們可以結合資料獲取邏輯,確保在路由切換前獲取到必要的資料。

export default {
  beforeRouteEnter(to, from, next) {
    // 在進入路由前獲取資料
    fetchData().then(() => {
      next();
    });
  }
}

以上是 Vue Router 高階部分的內容概述,涵蓋了導航守衛、路由懶載入、程式碼分割以及引數傳遞和資料獲取等高階主題。這些內容對於構建複雜、高效能的單頁面應用至關重要。

第7章 Vue Router 4在專案中的應用

7.1 專案結構規劃

在專案開始時,合理規劃專案結構是非常重要的。通常,我們會將路由配置檔案、元件、檢視等分別放置在不同的目錄中,以便於管理和維護。

/src
  /router
    index.js // 路由配置檔案
  /views // 檢視元件
    Home.vue
    About.vue
  /components // 可複用元件
    Header.vue
    Footer.vue
  App.vue
  main.js

7.2 路由配置與導航

index.js 中配置路由,並使用 <router-link><router-view> 進行導航和檢視渲染。

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({
  routes: [
    {
      path: '/',
      name: 'home',
      component: Home
    },
    {
      path: '/about',
      name: 'about',
      component: About
    }
  ]
});

App.vue 中使用:

<template>
  <div id="app">
    <router-link to="/">Home</router-link>
    <router-link to="/about">About</router-link>
    <router-view></router-view>
  </div>
</template>

7.3 路由守衛的應用

在專案中應用路由守衛,例如使用 beforeEach 進行許可權驗證。

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAuth && !isAuthenticated) {
    next('/login');
  } else {
    next();
  }
});

7.4 路由懶載入與程式碼分割

使用路由懶載入和程式碼分割提高應用效能。

const Home = () => import(/* webpackChunkName: "home" */ '@/views/Home.vue');
const About = () => import(/* webpackChunkName: "about" */ '@/views/About.vue');

第8章 基於角色的動態路由管理

8.1 動態路由的概念

動態路由允許我們根據使用者的角色或許可權動態地新增或移除路由。

8.2 使用者角色與許可權管理

在使用者登入後,根據使用者的角色或許可權資訊,動態配置路由。

8.3 動態新增路由

使用 router.addRoute 方法動態新增路由。

if (user.role === 'admin') {
  router.addRoute({
    path: '/admin',
    component: Admin,
    meta: { requiresAdmin: true }
  });
}

8.4 路由守衛與許可權驗證

結合路由守衛進行許可權驗證,確保使用者只能訪問其許可權範圍內的路由。

router.beforeEach((to, from, next) => {
  if (to.meta.requiresAdmin && !isAdmin) {
    next('/');
  } else {
    next();
  }
});

第9章 Vue Router 4與Vuex的結合

9.1 Vuex簡介

Vuex 是一個專為 Vue.js 應用程式開發的狀態管理模式。它採用集中式儲存管理應用的所有元件的狀態,並以相應的規則保證狀態以一種可預測的方式發生變化。

9.2 Vuex與Vue Router 4的整合

在 Vuex 中儲存路由狀態,如當前路由資訊、歷史記錄等。

// store/index.js
import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
  state: {
    currentRoute: null
  },
  mutations: {
    setCurrentRoute(state, route) {
      state.currentRoute = route;
    }
  },
  actions: {
    updateRoute({ commit }, route) {
      commit('setCurrentRoute', route);
    }
  }
});

9.3 使用Vuex管理路由狀態

在路由守衛中更新 Vuex 狀態。

router.beforeEach((to, from, next) => {
  store.dispatch('updateRoute', to);
  next();
});

9.4 實現路由的麵包屑導航

使用 Vuex 儲存的路由狀態實現麵包屑導航。

<template>
  <div>
    <router-link v-for="route in breadcrumbs" :key="route.path" :to="route.path">
      {{ route.name }}
    </router-link>
  </div>
</template>

<script>
export default {
  computed: {
    breadcrumbs() {
      const currentRoute = this.$store.state.currentRoute;
      // 根據當前路由生成麵包屑
      // ...
    }
  }
}
</script>

以上內容涵蓋了 Vue Router 4 在實際專案中的應用,包括專案結構規劃、路由配置、路由守衛、動態路由管理以及與 Vuex 的結合。這些知識點對於構建複雜的前端應用至關重要。

**附錄

A Vue Router 4 API參考**

Vue Router 4 提供了豐富的 API 用於路由管理。以下是一些核心 API 的簡要參考:

  1. createRouter: 建立並返回一個路由器例項。
import { createRouter, createWebHistory } from 'vue-router';

const routes = [
  // 路由配置陣列
];

const router = createRouter({
  history: createWebHistory(),
  routes,
});

export default router;

  1. router.beforeEach: 全域性前置守衛。
router.beforeEach((to, from, next) => {
  // ...
});

  1. router.addRoute: 動態新增路由。
router.addRoute({
  path: '/new-route',
  component: NewRouteComponent,
});

  1. router.replace: 替換當前路由。
router.replace('/new-route');

  1. router.push: 導航到一個新的路由。
router.push('/new-route');

  1. router.go: 在歷史記錄中前進或後退。
router.go(-1); // 後退一步
router.go(1); // 前進一步

  1. router.currentRoute: 當前路由資訊。
console.log(router.currentRoute.value); // 當前路由物件

  1. router.resolve: 解析路由記錄。
const resolvedRoute = router.resolve('/path');

  1. router.addRoutes: 動態新增多個路由。
router.addRoutes([
  // 路由配置陣列
]);

更多 API 請參考 Vue Router 4 的官方文件。

B Vue Router 4常見問題解答**

以下是一些 Vue Router 4 使用過程中常見的問題及解答:

  1. 如何在 Vue Router 4 中進行路由懶載入?

使用動態匯入語法 (import()) 實現路由元件的懶載入。

const Home = () => import(/* webpackChunkName: "home" */ './views/Home.vue');

  1. 如何在 Vue Router 4 中使用路由守衛?

可以在路由配置中使用 beforeEnter 守衛,或者在全域性範圍內使用 router.beforeEach

  1. 如何動態新增路由?

使用 router.addRoute 方法動態新增路由。

  1. 如何在 Vue Router 4 中獲取當前路由?

透過 router.currentRoute 獲取當前路由資訊。

  1. 如何在 Vue Router 4 中進行路由導航?

使用 router.pushrouter.replace 進行路由導航。

C Vue Router 4版本更新日誌**

Vue Router 4 的版本更新日誌記錄了每個版本的更新內容、新特性、改進和修復的 bug。以下是一些主要的更新內容:

  • 4.0.0: Vue Router 4 的初始版本,與 Vue 3 相容,引入了新的 API 和改進。
  • 4.0.1: 修復了一些在 4.0.0 中引入的 bug。
  • 4.x.x: 隨後的版本繼續修復 bug、改進效能和增加新的功能。

相關文章