RitoLabo

VueRouter基本ルーティング記法まとめ

  • 公開:
  • カテゴリ: JavaScript Vue.js
  • タグ: Vue,Routing,VueCLI,VueRouter,SPA

Vue.jsでSPA(シングルページアプリケーション)を開発する際にVueRouterを利用する事で、 HTML5 History APIを用いたHistory管理と、SPAでありながら画面切り替えの挙動を持つ事が出来ます。

今回は、VueRouterの基本的なルーティングパターンを見ていきます。

アジェンダ
  1. 開発環境
  2. ルーティングをネストする
  3. URL履歴操作と任意のコンポーネントへの遷移
  4. リダイレクト・エイリアス
  5. 名前付きルート
  6. 名前付きビュー
  7. ルートコンポーネントにプロパティを渡す
    1. Booleanモード
    2. Objectモード
    3. Functionモード

開発環境

今回の開発環境は以下の通りです。

  • Vue.js 2.x
  • Vue CLI 3.x
  • Vue Router 3.x

今回は、VueRouterの公式ガイドに沿って各々のルーティングを見ていきたいと思います。 多少順番は前後しますがなるべく同じワードを使うようにしているので、より詳細を確認したい場合は併せてそちらも参照すると良いと思います。

VueRouter公式ガイド
https://router.vuejs.org/ja/

また、開発環境や最もベーシックなルーティングに関しては以下を確認してください。
VueRouterの基本とルーティングを構築するはじめの一歩

ルーティングをネストする

途中まで同一のルーティングで、そこからバリエーションが生まれたりするルーティングはネストできます。

コンポーネント群
<!-- App.vue -->
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/product">Product</router-link>
</div>
<router-view/>
</div>
</template>

<!-- views/Home.vue -->
<template>
<div class="home">
<h1>Home</h1>
</div>
</template>

<!-- views/Product.vue -->
<template>
<div class="product">
<h1>Product</h1>
<div class="nav">
<router-link to="/product/A">ProductA</router-link> |
<router-link to="/product/B">ProductB</router-link>
</div>
<router-view></router-view>
</div>
</template>

<!-- views/products/ProductA.vue -->
<template>
<div class="productA">
<h2>This is productA</h2>
</div>
</template>

<!-- views/products/ProductB.vue -->
<template>
<div class="productB">
<h2>This is productB</h2>
</div>
</template>

Product.vueにて、Productに関連するリンクを生成しています。 rootであるAppのルーティングからさらにネストしている状態です。

router.js
import Vue from 'vue'
import Router from 'vue-router'
import Home from './views/Home.vue'
import Product from './views/Product.vue'
import ProductA from './views/products/ProductA.vue'
import ProductB from './views/products/ProductB.vue'

Vue.use(Router)

export default new Router({
mode: 'history',
base: process.env.BASE_URL,
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/Product',
name: 'Product',
component: Product,
children: [
{
path: 'A',
component: ProductA
},
{
path: 'B',
component: ProductB
}
]
}
]
})

Productのルーティングにてchildrenプロパティを定義し、子(ネスト)のルーティングを定義しています。

サンプルページ

URL履歴操作と任意のコンポーネントへの遷移

任意のアクションなどからHistoryを操作し、ブラウザの「進む」「戻る」を実行できます。

src/App.vue
<script>
export default {
name: 'Root',
methods: {
forward () {
// 1つ前へ
this.$router.forward()
},
back () {
// 1つ先へ
this.$router.back()
},
forwardDouble () {
// 2つ先へ
this.$router.go(2)
},
backDouble () {
// 2つ前へ
this.$router.go(-2)
}
}
}
</script>

以下、1つずつ解説していきます。

this.$router.forward()

forward()メソッドでブラウザの履歴を1つ進める事が出来ます。

this.$router.back()

back()メソッドでブラウザの履歴を1つ戻す事が出来ます。

this.$router.go(integer number)

go()メソッドでブラウザの履歴を引数に渡した数値の分だけ進めるたり戻す事が出来ます。負の数を指定すれば「戻る」になります。

サンプルページ

また、任意のコンポーネントへ遷移させる事もできます。

src/App.vue
push () {
// Historyは追加される
this.$router.push('Jump')
},
replace () {
// 現在のhistoryを置換する
this.$router.replace('Jump')
}

push()replace()も、引数にコンポーネント名(router.jsのnameプロパティetc)を 渡す事でそのコンポーネントへ遷移しますが、両者の違いは、遷移時にURL履歴に「追加する」か、現在のHistoryを「上書きする」かです。

サンプルページ

サンプルページで説明すると、Home→Page01→Page02→Page03→Page04→Page05までナビゲーションで遷移した後に、 push() を行った場合は、URL履歴に追加されるので、その後でback()を行うとPage05に戻りますが、 replace()を行った場合は、現在居るPage05の履歴を上書きするので、back()を行うとPage04に戻る事になります。

リダイレクト・エイリアス

任意のルーティングに対してリダイレクトを設定できます。

router.js
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/sample',
name: 'sample',
component: Sample
},
// redirect
{ path: '/page/01', redirect: '/sample' }, // pathで指定
{ path: '/page/02', redirect: { name: 'sample' } }, // nameで指定
]

リダイレクト先はpathもしくはnameプロパティで指定できます。

src/App.vue
<router-link to="/">Home</router-link> |
<router-link to="/sample">Sample</router-link> |
<router-link to="/page/01">Page01</router-link> |
<router-link to="/page/02">Page02</router-link>

ルーティングでリダイレクトを設定してあるので、 /page/01/page/02 を踏んだ場合のアクセスは/sampleになります。

また、ルーティングに対してエイリアスを設定する事も出来ます。

router.js
{
path: '/sample',
name: 'sample',
component: Sample,
alias: '/smp' // alias
}

これで、/smpのルーティングは同じく/sampleになります。

サンプルページ

名前付きルート

ルーティングに名前をつけておくと、遷移先の指定の際に便利です。

router.js
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/sample/path/to/destination',
name: 'sample', // 名前をつけておく
component: Sample
},
]

nameプロパティを定義しておきます。

src/App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |

<!-- パスが長いと色々と面倒 -->
<!-- <router-link to="/sample/path/to/destination">Sample</router-link> -->

<!-- 名前で指定できる -->
<router-link :to="{ name: 'sample' }">Sample</router-link>

<!-- パラメータを渡す場合 -->
<!-- <router-link :to="{ name: 'sample', params: { id: 1 } }">Sample</router-link> -->

</div>
<button @click="toPath">toPath</button> |
<button @click="toName">toName</button>
<router-view/>
</div>
</template>

<script>
export default {
methods: {
// こっちで遷移させる場合も使える
toPath () {
this.$router.push('/sample/path/to/destination')
},
toName () {
this.$router.push({ name: 'sample' })
}
}
}
</script>

nameプロパティを定義しておけば、パスの指定も簡単になります。 また、スクリプト側で遷移させる場合でも名前付きルートが使えます。

サンプルページ

名前付きビュー

ビューに名前をつける事ができて、ルーティング時にそれらを定義付けて呼び出す事が出来ます。

src/App.vue
<template>
<div id="app">
<div id="nav">
<router-link to="/">Home</router-link> |
<router-link to="/main">Main</router-link>
</div>
<router-view/>
<router-view name="sub01"/>
<router-view name="sub02"/>
</div>
</template>

router-viewコンポーネントが3つある事に気づくでしょうか。 一番上がこれまで使用してきたデフォルトのビューで、下の2つにはそれぞれ名前がついています。

router.js
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/main',
name: 'main',
components: {
default: Main,
sub01: Sub01,
sub02: Sub02
}
}
]

componentsプロパティでそれぞれのビューを紐づけてやる事で、狙ったルーティングでそれらを呼び出す事が可能になります。

サンプルページ

ちなみに、ネストして少し複雑になったルーティングでも使えます。

router.js
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/setting',
name: 'setting',
component: Setting,
children: [
{
path: 'A',
component: SettingA
},
{
path: 'B',
components: {
default: SettingB,
sub: SettingBSub
}
}

]
}
]
src/Setting.vue
<template>
<div class="setting">
<h1>Setting</h1>
<main>
<div id="left">
<nav>
<ul>
<router-link tag="li" to="/setting/A">Setting A</router-link>
<router-link tag="li" to="/setting/B">Setting B</router-link>
</ul>
</nav>
</div>
<div id="right">
<router-view></router-view>
<router-view name="sub"></router-view>
</div>
</main>
</div>
</template>

サンプルページ

ルートコンポーネントにプロパティを渡す

規模が大きくなってきたり、取り扱うパラメータが増えてくると、this.$route.xxxみたいなのが辛くなってきます。 また、本当は独立していたいコンポーネントですが、$routeのおかげで依存が生まれてしまうので、そうじゃなくて、 コンポーネントとルーターを分離させてすっきりできるよ。というお話です。

公式ガイドでは3つのモードを紹介しています。
https://router.vuejs.org/ja/guide/essentials/passing-props.html

Booleanモード

ルーティングでpropsプロパティをtrueにする(Booleanで設定する)方法です。

router.js
routes: [
{
path: '/',
name: 'home',
component: Home
},
{
path: '/page/:id',
name: 'page',
component: Page,
props: true, // Boolean mode
}
]

これで、いつも使っているpropsの要領でコンポーネント側から利用できるようになります。

views/Page.vue
<template>
<div class="page">
<h1>Page</h1>
<button @click="dump">dump</button>
<p>
{{ id }}
</p>
</div>
</template>

<script>
export default {
props: ['id'],
methods: {
dump () {
console.log(this.id)
}
}
}
</script>

サンプルページ

this.$route.が不要になりましたね。すっきりです。

Objectモード

ルーティングでpropsプロパティにオブジェクトを渡して利用する方法です。

router.js
{
path: '/page/:id',
name: 'page',
component: Page,
props: {
propA: 'AAA',
propB: 'BBB',
propC: 'CCC'
}
}
views/Page.vue
<template>
<div class="page">
<h1>Page</h1>
<button @click="dump">dump</button>
<p>
{{ propA }} | {{ propB }} | {{ propC }}
</p>
</div>
</template>

<script>
export default {
props: ['propA', 'propB', 'propC'],
methods: {
dump () {
console.log(this.propA)
console.log(this.propB)
console.log(this.propC)
}
}
}
</script>

サンプルページ

Functionモード

ルーティングでpropsプロパティを関数で定義して利用する方法です。 定義時に一処理かませたりもできます。

router.js
{
path: '/page/:id',
name: 'page',
component: Page,
props: route => ({
id: Number(route.params.id) // URLパラメータは文字列で渡ってくるのでここで予め数値型へキャストする。みたいなこともできる。
})
}
views/Page.vue
<template>
<div class="page">
<h1>Page</h1>
<button @click="dump">dump</button>
<p>
{{ id }}
</p>
</div>
</template>

<script>
export default {
props: {
id: Number
},
methods: {
dump () {
console.log(this.id)
}
}
}
</script>

サンプルページ

まとめ

Vue Routerでの基本的なルーティング記法を見ていきました。 ルーティングって実はそんなに沢山の基本パターンは無いのかもなと思いつつ、あとはここに状況や条件が絡んできてより複雑なものが増えていく という流れだと思うので、基本はしっかり抑えておきたいですね。

サンプルコード