Vue Router — ネストルート
テクノロジ系 / L04 routing — ルーティング
Vue Router — ネストルート
children で階層化
const routes = [
{
path: "/users",
component: UserLayout,
children: [
{ path: "", component: UserList }, // /users
{ path: ":id", component: UserDetail }, // /users/:id
{ path: ":id/edit", component: UserEdit }, // /users/:id/edit
],
},
];children で子ルート。
子の path は親を含めない (相対指定)。
RouterView をネスト
<!-- UserLayout.vue -->
<template>
<div class="user-section">
<aside>
<UserSidebar />
</aside>
<main>
<RouterView /> <!-- 子ルートが描画される -->
</main>
</div>
</template>→ /users でも /users/123 でも UserLayout 内に描画。
共有レイアウトのメリット
- ヘッダ・サイドバーを毎ページ書かない
- 子ルート切替時に 親のDOMは再利用 (高速)
- 共通ロジック (認証 / 通知) を親に置ける
ネストの再描画コスト
/users → /users/1 → /users/2 ↑ UserLayout は1度だけ作られる、UserList ↔ UserDetail だけ切り替わる
→ 親側で重いデータ取得をしても、子切替で再取得されない。
ナビゲーション体験が滑らか。
ネストの典型例
[
{
path: "/",
component: MainLayout,
children: [
{ path: "", component: HomePage },
{ path: "about", component: AboutPage },
{
path: "dashboard",
component: DashboardLayout,
children: [
{ path: "", component: DashboardHome },
{ path: "settings", component: Settings },
{ path: "users", component: Users },
],
},
],
},
{ path: "/login", component: LoginPage }, // レイアウト外
]ログイン画面など特殊なものは親レイアウトから外す。
まとめ
childrenで子ルート (path は相対)- 親コンポーネントに
<RouterView>を置く - レイアウトとコンテンツの分離が自然
- 共通DOMは再描画されず性能良し
- レイアウト外の特殊ページは親から外す
最後は ナビゲーションガード。
考えてみよう
既定では正解・不正解の判定はしません。自分のペースで「答えを見る」を。採点してほしい場合だけ「採点してほしい」を押してください。
Lv1: 基本 — children
問題
const routes = [
{
path: "/users",
component: () => import("./pages/UsersLayout.vue"),
children: [
{ path: "", component: () => import("./pages/UserList.vue") },
{ path: ":id", component: () => import("./pages/UserDetail.vue") },
{ path: ":id/edit", component: () => import("./pages/UserEdit.vue") },
],
},
];<!-- UsersLayout.vue -->
<script setup>
import { RouterView } from "vue-router";
</script>
<template>
<div class="users-section">
<aside><nav>Sidebar</nav></aside>
<main><RouterView /></main>
</div>
</template>合格基準
- /users で UserList
- /users/1 で UserDetail
- どちらも UsersLayout 内に描画
Lv2: 応用 — レイアウトの DOM 保持
問題
<!-- UsersLayout.vue -->
<script setup>
import { onMounted, onUnmounted } from "vue";
onMounted(() => console.log("Layout mounted"));
onUnmounted(() => console.log("Layout unmounted"));
</script>/users → /users/1 → /users/2 と遷移して、Layout が 1回しか mount されない ことを観察。
合格基準
- ネスト内遷移で親再描画なし
- 高速
Lv3: 発展 — 多階層ネスト
問題
const routes = [
{
path: "/",
component: MainLayout,
children: [
{ path: "", component: Home },
{
path: "dashboard",
component: DashboardLayout,
children: [
{ path: "", component: DashboardHome },
{ path: "settings", component: Settings },
{
path: "users",
component: UserSection,
children: [
{ path: "", component: UserList },
{ path: ":id", component: UserDetail },
],
},
],
},
],
},
{ path: "/login", component: LoginPage }, // 親レイアウト外
];/dashboard/users/1 で 3階層のレイアウトが入れ子表示される。
合格基準
- 3階層 nest 動作
- /login だけレイアウト外
提出
submission.md に3問の回答を。