1. Home
  2. JavaScript
  3. Vue.js
  4. VueRouter基本ルーティング記法まとめ

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

  • 公開日
  • 更新日
  • カテゴリ:Vue.js
  • タグ:Vue,Routing,VueCLI,VueRouter,SPA
VueRouter基本ルーティング記法まとめ

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

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

Contents

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

サンプルコード

Author

rito

  • Backend Engineer
  • Tokyo, Japan
  • PHP 5 技術者認定上級試験 認定者
  • 統計検定 3 級