本文 AI 產出,尚未審核

Vue3 路由系統(Vue Router 4)

主題:動態路由(/user/:id)


簡介

在單頁應用(SPA)中,路由是連結畫面與資料的橋樑。Vue Router 4 為 Vue3 官方提供的路由解決方案,支援 動態路由、懶載入、嵌套路由等功能。
動態路由(例如 /user/:id)允許我們在 URL 中使用變數,讓同一個元件根據不同參數呈現不同內容,這在使用者個人頁面、商品細節、文章閱讀等情境中非常常見。

本篇文章將從概念說明、實作範例、常見陷阱與最佳實踐,逐步帶你掌握 Vue Router 4 的動態路由,並提供可直接套用在專案中的程式碼範例,適合 初學者到中級開發者


核心概念

1. 什麼是動態路由?

動態路由是指路由路徑中包含 參數占位符(parameter placeholder),以冒號 : 開頭。例如:

/user/:id

當使用者瀏覽 /user/123 時,id 參數的值會被自動解析為 123,並可在對應的元件中取得。

2. 在 Vue Router 4 中定義動態路由

router/index.js(或 router.ts)中,我們使用 createRoutercreateWebHistory 建立路由表,將動態路由寫入 routes 陣列:

// router/index.js
import { createRouter, createWebHistory } from 'vue-router'
import UserDetail from '@/views/UserDetail.vue'

const routes = [
  {
    path: '/user/:id',          // <-- 動態路由
    name: 'UserDetail',
    component: UserDetail,
    props: true                 // <-- 讓路由參數自動作為 props 傳入元件
  },
  // 其他路由...
]

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

export default router
  • props: true:將路由參數(id)直接作為元件的 props,讓元件更易於測試與重用。

3. 在元件中取得參數

有三種常見方式:

方式 說明
props(建議) 直接在 setupdata 中使用 props.id
useRoute() 透過 Vue Router 的 composable 取得 route.params.id
$route.params 在 Options API 中使用 this.$route.params.id

範例 1:使用 props

<!-- src/views/UserDetail.vue -->
<template>
  <div>
    <h2>使用者資料(ID: {{ id }})</h2>
    <p v-if="user">姓名:{{ user.name }}</p>
    <p v-else>載入中…</p>
  </div>
</template>

<script setup>
import { ref, onMounted } from 'vue'
import { useFetchUser } from '@/composables/useFetchUser' // 假設的自訂 Hook

// 透過 props 取得路由參數
defineProps({
  id: {
    type: String,
    required: true
  }
})

const user = ref(null)

// 假設有一個 API 呼叫的 composable
onMounted(async () => {
  user.value = await useFetchUser(id)
})
</script>

範例 2:使用 useRoute()

<script setup>
import { ref, onMounted } from 'vue'
import { useRoute } from 'vue-router'
import { fetchUser } from '@/api/user'

const route = useRoute()
const userId = route.params.id          // 取得路由參數
const user = ref(null)

onMounted(async () => {
  user.value = await fetchUser(userId)
})
</script>

範例 3:使用 Options API

export default {
  name: 'UserDetail',
  data() {
    return {
      user: null
    }
  },
  async created() {
    const id = this.$route.params.id
    this.user = await this.$store.dispatch('user/fetchById', id)
  }
}

4. 動態路由的懶載入(Code Splitting)

若使用者頁面較大,建議 懶載入 元件,以減少首屏載入時間:

const routes = [
  {
    path: '/user/:id',
    name: 'UserDetail',
    component: () => import('@/views/UserDetail.vue'), // 動態匯入
    props: true
  },
  // ...
]

Webpack(或 Vite)會自動把 UserDetail.vue 打包成獨立的 chunk,只有在實際切換到 /user/:id 時才下載。

5. 監聽路由參數變化

在同一個元件內切換不同 id(例如從 /user/1 直接點擊連結到 /user/2),元件不會重新掛載,必須手動偵測參數變化:

<script setup>
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { fetchUser } from '@/api/user'

const route = useRoute()
const user = ref(null)

const loadUser = async (id) => {
  user.value = await fetchUser(id)
}

// 初始載入
loadUser(route.params.id)

// 監聽 id 變化
watch(
  () => route.params.id,
  (newId, oldId) => {
    if (newId !== oldId) loadUser(newId)
  }
)
</script>

常見陷阱與最佳實踐

陷阱 說明 解決方式
參數未轉型 route.params.id 預設為字串,若後端需要數字會出錯。 在取得參數後使用 Number(id)parseInt(id, 10) 轉型。
忘記加 props: true 直接在元件使用 props.id 卻未設定,會得到 undefined 確認路由設定中加入 props: true,或改用 useRoute()
路由守衛未考慮參數 在全局守衛中只檢查 to.name,忽略 to.params.id 會造成權限檢查錯誤。 在守衛裡同時驗證 to.params.id 是否符合授權條件。
同一路由不同參數不重新掛載 直接在列表點擊不同 ID 時,created/mounted 不會再次執行。 使用 watch 監聽 route.params 或在 beforeRouteUpdate 鉤子中處理。
SEO 需求 SPA 預設不利於搜尋引擎抓取動態參數頁面。 搭配 SSR(Nuxt3)或 Prerender 方案,或在服務端提供對應的靜態快照。

最佳實踐

  1. 使用 props: true,讓元件保持純粹、易測。
  2. 懶載入 動態路由元件,提升首屏效能。
  3. 統一參數轉型(如 Number(id)),避免類型錯誤。
  4. watchbeforeRouteUpdate 中處理參數變化,確保資料同步。
  5. 加入路由守衛meta.requiresAuth)保護需要授權的動態頁面。

實際應用場景

場景 為何使用動態路由 範例路徑
使用者個人檔案 每個使用者都有唯一 ID,透過 /user/:id 顯示不同資訊。 /user/42
商品細節頁 商品編號作為參數,讓同一個 ProductDetail 元件呈現不同商品。 /product/9876
部落格文章 文章 slug 或 ID 作為路由參數,支援 SEO 友善 URL。 /blog/vue3-router
多層嵌套的管理介面 例如 /admin/project/:projectId/task/:taskId,同時取得兩個參數。 /admin/project/5/task/12
搜尋結果分頁 透過 /search/:query/page/:pageNum 動態切換結果與分頁。 /search/vue/page/3

小技巧:如果路由參數需要驗證(例如只能是正整數),可以在路由設定中加入正則表達式:

{
  path: '/user/:id(\\d+)',   // 只接受數字
  name: 'UserDetail',
  component: UserDetail,
  props: true
}

總結

  • 動態路由 是 SPA 中最常見的需求之一,Vue Router 4 提供了簡潔且彈性的寫法。
  • 透過 props: true懶載入watch 參數變化等技巧,我們可以寫出 可維護、效能佳 的元件。
  • 注意 類型轉換路由守衛重新掛載 等常見陷阱,並依照 最佳實踐 進行開發,能大幅降低錯誤率與維護成本。

掌握了 /user/:id 這類動態路由後,你就能在 Vue3 專案中輕鬆建構各式「依參數呈現」的頁面,從使用者個人檔案到商品細節,都能快速上手、穩定運作。祝開發順利! 🚀