跳至主要內容
Skip to content

巢狀路由 (Nested Routes)

在後台管理系統 (Dashboard) 中,我們常看到這樣的佈局:

  • 最外層:是 Header 與 Sidebar。
  • 中間層:切換不同的功能模組 (如「用戶管理」)。
  • 最內層:在用戶管理中,又可以切換「列表」、「詳情」、「設定」。

這種「視圖中有視圖」的結構,在 Vue Router 中就對應到 巢狀路由


一、 觀念:路由對應組件

最核心的觀念只有一句話: 巢狀的 URL 對應巢狀的組件結構。

text
/user/foo/profile                     /user/foo/posts
+------------------+                  +-----------------+
| User (Route)     |                  | User (Route)    |
| +--------------+ |                  | +-------------+ |
| | Profile      | |  +------------>  | | Posts       | |
| |              | |                  | |             | |
| +--------------+ |                  | +-------------+ |
+------------------+                  +-----------------+

要實現這一點,我們需要在路由配置中使用 children 陣列。


二、 配置 Children

假設我們有一個 /user/:id 頁面,裡面又要切換 ProfilePosts

javascript
// router/index.js
const routes = [
  {
    path: "/user/:id",
    component: User,
    // children 陣列定義子路由
    children: [
      {
        // 1. 當網址是 /user/:id/profile 時渲染
        path: "profile",
        component: UserProfile,
      },
      {
        // 2. 當網址是 /user/:id/posts 時渲染
        path: "posts",
        component: UserPosts,
      },
    ],
  },
];

WARNING

注意路徑寫法:子路由的 path 不要/ 開頭。

  • profile (正確) -> 解析為 /user/:id/profile
  • /profile (錯誤) -> 解析為根目錄 /profile

三、 必備:第二層 RouterView

定義好 children 還不夠,我們還需要在父組件 (User.vue) 中放置一個 <router-view>,這樣父組件才能知道要把子組件渲染在哪裡。

html
<!-- User.vue -->
<template>
  <div class="user-layout">
    <h1>User: {{ $route.params.id }}</h1>

    <!-- 導航列 -->
    <router-link :to="`/user/${$route.params.id}/profile`">Profile</router-link>
    <router-link :to="`/user/${$route.params.id}/posts`">Posts</router-link>

    <hr />

    <!-- 關鍵:子路由出口 -->
    <!-- UserProfile 或 UserPosts 會顯示在這裡 -->
    <router-view></router-view>
  </div>
</template>

四、 預設子路由 (Default Child Route)

如果你訪問 /user/123,但沒有加 /profile/posts,視圖區塊會是一片空白。

通常我們會希望有一個「預設頁面」。這可以透過留空 path 來實現:

javascript
children: [
  {
    // 當網址確切為 /user/:id 時渲染
    path: "",
    component: UserHome,
  },
  // ...其他子路由
];

五、 多層巢狀

Vue Router 支援無限層級的巢狀。你可以在子路由中再定義 children,然在子組件中再放 router-view

雖然技術上可行,但在 UI 設計上,超過 3 層的巢狀會讓使用者感到困惑。如果結構太深,建議考慮使用 命名視圖 (Named Views) 或將頁面扁平化設計。


總結

  1. 使用 children 陣列配置子路由。
  2. 子路由 path 不要加 /
  3. 父組件必須包含 <router-view> 作為子路由的出口。
  4. 使用空字串 path: '' 來定義預設子路由。

掌握了結構,下一章我們要來學學如何用 JavaScript 來控制這些跳轉:程式化導航

下一章:程式化導航