本文 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)中,我們使用 createRouter 與 createWebHistory 建立路由表,將動態路由寫入 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(建議) |
直接在 setup 或 data 中使用 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 方案,或在服務端提供對應的靜態快照。 |
最佳實踐:
- 使用
props: true,讓元件保持純粹、易測。 - 懶載入 動態路由元件,提升首屏效能。
- 統一參數轉型(如
Number(id)),避免類型錯誤。 - 在
watch或beforeRouteUpdate中處理參數變化,確保資料同步。 - 加入路由守衛(
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 專案中輕鬆建構各式「依參數呈現」的頁面,從使用者個人檔案到商品細節,都能快速上手、穩定運作。祝開發順利! 🚀