Vue.jsの公式ライブラリVueRouterを使うとSPAのアプリケーションやサイトを簡単に作成することができます。
その際、ルートはネスト(階層構造やネスト)させることができます。
ネストしたルートとは何か?
例えば、ユーザー毎の専用ページ「~/user/ユーザーid」というURLの下に、「~/user/ユーザーid/profile」と、「~/user/ユーザーid/blog」の2つのページが存在するとします。
これを作る時に、いちいち3つのルートを作成するのではなく、ユーザー毎の専用ページ「~/user/ユーザーid」を親として、その配下に「~/user/ユーザーid/profile」と、「~/user/ユーザーid/blog」の2つのページを作成することができます。
こうするとルートやWEBページの構造がわかりやすくなります。
user/userId
|- profile
└- blog
ネストしたルートの作成時のポイントと注意点
ネストしたルートを作成するときのポイントと注意点は以下になります。
ネストしたルートの作成手順
実際にネストしたルートの作成する手順を実例で解説します。
親となるルートの中にchildrenオブジェクトを作成する
まずはネストしたルートを作成するため、親となるルートの中にchildrenオブジェクトを作成します。
const router = new VueRouter({
routes: [
{
path: '親ルートのパス',
component: 親ルートのhtmlの内容,
children: [
//子ルートを定義
{
path: '子ルートのパス',
component: 子ルートのhtmlの内容
}
]
}
]
})
実例
親ルートのパスを「/user/:id」とし、その下に「/user/:id/profile」と「/user/:id/blog」の2つの子ルートを作成します。
//子ルートのコンポーネント
const Profile = {
template: `
<div class="profile">
<h3>Profileページです。</h3>
<p>名前:{{ $route.params.name }}</p>
</div>`
}
const Blog = {
template: `
<div class="blog">
<h3>Blogページです。</h3>
<p>まだブログは投稿されていません。</p>
</div>`
}
//VueRouterでネストしたルートを定義
const router = new VueRouter({
routes: [
{
path: '/user/:name',
name: 'user',
component: User,
children: [
{
path: 'profile',
component: Profile
},
{
path: 'blog',
component: Blog
}
]
}
]
})
const app = new Vue({
router: router
}).$mount('#app')
子ルートのパスはpath: 'profile',
のように、親ルートの「/user/:name」を除外していることに注意してください。
childrenオブジェクトにしたことで、実際のルートは「/user/:name/profile」となります。
親のtemplateの中に、router-viewタグを設置する
現状の状態では、子ルートのコンポーネントを表示する場所がありません。
親のコンポーネントの中に、router-viewタグを設置することで、子ルートのコンポーネントがそこに表示されます。
<router-view></router-view>
実例
親のコンポーネントを作成しその中に、子ルートへのリンクと、子ルートのコンポーネントの表示領域を作成します。
//親ルートのコンポーネント
const User = { template:`
<div class="user">
<h2>こんにちは「{{$route.params.name}}」さん</h2>
<p>ここはあなたの専用ページです<p>
<!-- ネストしたルート1 -->
<router-link to="/user/Steve/profile">>プロファイルを表示する</router-link>
<br>
<!-- ネストしたルート2 -->
<router-link to="/user/Steve/blog">>ブログを表示する</router-link>
<hr><br>
<!-- コンポーネントの表示領域 -->
<router-view></router-view>
</div>`
}
以上で子ルートの設定は完了です。
htmlに親コンポーネントのリンクと表示領域を設定する
最後にhtmlファイルに親コンポーネントのリンクと表示領域を作成します。
<router-link to="親ルートのパス">アンカーテキスト</router-link>
<router-view></router-view>
実例
htmlファイルに親ルート「/user/Steve」へのリンクと、親コンポーネントの表示領域を設置します。
<body>
<div id="app">
<!-- userページへのリンク -->
<router-link to="/user/Steve">・ユーザー専用ページへのリンク</router-link>
<!-- コンポーネントの表示領域 -->
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script src="https://unpkg.com/vue-router@3.0.7/dist/vue-router.js"></script>
</body>
以上で設定は完了です。
ブラウザの表示
デフォルトでは親ルートのリンクのみが表示された状態です。
↓ リンクをクリック
リンクをクリックすると、親コンポーネントの内容が表示されます。
↓「プロファイルを表示する」をクリック
親コンポーネントの中のrouter-viewの部分に該当する子ルートのコンポーネントが表示されます。
↓「ブログを表示する」をクリック
親コンポーネントの中のrouter-viewの部分に該当する子ルートのコンポーネントが表示されます。
(参考)ネストしたルートのコード
参考として、ネストしたルートの全体のコードを以下にまとめておきます。
.jsファイル
//親ルートのコンポーネント
const User = { template:`
<div class="user">
<h2>こんにちは「{{$route.params.name}}」さん</h2>
<p>ここはあなたの専用ページです<p>
<!-- ネストしたルート1 -->
<router-link to="/user/Steve/profile">>プロファイルを表示する</router-link>
<br>
<!-- ネストしたルート2 -->
<router-link to="/user/Steve/blog">>ブログを表示する</router-link>
<hr><br>
<!-- コンポーネントの表示領域 -->
<router-view></router-view>
</div>`
}
//子ルートのコンポーネント
const Profile = {
template: `
<div class="profile">
<h3>Profileページです。</h3>
<p>名前:{{ $route.params.name }}</p>
</div>`
}
const Blog = {
template: `
<div class="blog">
<h3>Blogページです。</h3>
<p>まだブログは投稿されていません。</p>
</div>`
}
//VueRouterでネストしたルートを定義
const router = new VueRouter({
routes: [
{
path: '/user/:name',
name: 'user',
component: User,
children: [
{
path: 'profile',
component: Profile
},
{
path: 'blog',
component: Blog
}
]
}
]
})
const app = new Vue({
router: router
}).$mount('#app')
.htmlファイル
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Vue Router</title>
</head>
<body>
<div id="app">
<!-- userページへのリンク -->
<router-link to="/user/Steve">・ユーザー専用ページへのリンク</router-link>
<!-- コンポーネントの表示領域 -->
<router-view></router-view>
</div>
<script src="https://cdn.jsdelivr.net/npm/vue@2.6.11"></script>
<script src="https://unpkg.com/vue-router@3.0.7/dist/vue-router.js"></script>
</body>
</html>