関連:
Vueチートシートに引き続き公式チュートリアルの抜粋です。
参考
概要
-
vue-router = Vue.jsにおける公式のルータ
- SPAのためのページルーティング機能を提供する
-
公式によると以下を特徴としている:
- ネストされたルート/ビューマッピング
- モジュール式、コンポーネントベースのルータ構造
- ルートパラメータ、クエリ、ワイルドカード
- Vue.js の transition 機能による、transition エフェクトの表示
- 細かいナビゲーションコントロール
- 自動で付与される active CSS クラス
- HTML5 history モードまたは hash モードと IE9 の互換性
- カスタマイズ可能なスクロール動作
導入
-
CDNを unpkg.com が提供している
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script> <!-- Vue.js本体の後に記述すると自動ロードされる --> <script src="https://unpkg.com/vue-router@2.0.0/dist/vue-router.js"></script>
-
webpack環境の場合はnpmを利用できる
$ npm install vue-router
import Vue from 'vue' import VueRouter from 'vue-router' // use()によって明示的にロードする Vue.use(VueRouter)
基本
-
HTML側は:
-
<router-view>
コンポーネントに現在の画面が表示される -
<router-link>
コンポーネントで画面遷移を明示する
<div id="app"> <p> <router-link to="/foo">Foo</router-link> <router-link to="/bar">Bar</router-link> </p> <router-view></router-view> </div>
-
-
js側は:
-
VueRouter
を作成しrootインスタンスに渡すことでルーティングを設定する// ルーティングを定義する const router = new VueRouter({ routes: [ { path: '/foo', component: Foo }, { path: '/bar', component: Bar } ], }) // rootインスタンスに渡す const vm = new Vue({ router }).$mount('#app')
-
this.$route
でそのルーティングの情報、this.$router
でルーティング全体の情報にコンポーネントからアクセスできるexport default { computed: { username () { return this.$route.params.username } }, methods: { goBack () { window.history.length > 1 ? this.$router.go(-1) : this.$router.push('/') } } }
-
ルーティング方法
動的なマッチング
-
Rails等と同じく、コロン : を使ってパラメータを含むルーティングを設定できる
const router = new VueRouter({ routes: [ { path: '/user/:id', component: User } ] })
-
URLが含むパラメータは
$route.params
で参照できるconst User = { template: '<span>{{ $route.params.id }}</span>' }
-
同じrouteの異なるパラメータで画面遷移しても、vue-routerは画面を再描画しない
- ライフサイクルフックが呼ばれないため、変更を検知したい場合はwatchを使う
{ watch: { '$route' : (to, from)=> ... } }
-
マッチパターンのワイルドカードとして
*
が使える- マッチしたパターンは
$route.params.pathMatch
で参照できる - ルーティングは先に宣言されたパターンのほうが優先される
const router = new VueRouter({ routes: [ { path: '/user-*', component: User }, { path: '*', component: NotFound }, // 全てにマッチ ] })
- マッチしたパターンは
ネスト
-
ネストされたルーティングに対し、
<view-router>
もネストすることで対応できる<div id="root"> <!-- トップレベル --> <router-view></router-view> </div>
const User = { template: ` <div class="user"> <!-- 2階層目のview --> <router-view></router-view> </div> ` } const router = new VueRouter({ routes: [ { path: '/user/:id', component: User, children: [ // /user/:id/profileにマッチした時に2階層目のrouter-viewに表示される { path: 'profile', component: UserProfile } // /user/:id の場合に2階層目に表示させたい場合 { path: '', component: UserDefault } ] } ] })
同階層に複数のviewを配置する
-
複数のviewを並列したい場合は名前をつけて管理する
<!-- 未指定は "default" となる --> <router-view ></router-view> <router-view name="a"></router-view> <router-view name="b"></router-view>
// ルーティングの際にcomponentではなくcomponentsを指定する const router = new VueRouter({ routes: [ { path: '/', components: { default: Foo, a: Bar, b: Baz } } ] })
コードによる制御
vue-routerのページ履歴はES標準の window.history
に近似する
-
<router-link>
によって静的なリンクを作成するほか、コードにより画面遷移をトリガできる// 単純な遷移 this.$router.push('/user/123') // 名前による指定 // /user/:id のrouteがあった場合に /user/123 に遷移する this.$router.push({ name: 'user', { id: '123' }}) // パラメータを渡す // /foo?bar=baz this.$router.push({ path: 'foo', query: { bar: 'baz' }})
-
replace()
を使うとhistoryにURLをスタックせずに遷移できるthis.$router.replace('/user/123')
<!-- router-linkも同様にreplace指定できる --> <router-link to="/foo" replace></router-link>
-
go()
を使うと指定した数のスタックを進んだり戻ったりできる// 進む this.$router.go(1) // 戻る this.$router.go(-1)
名前付きのroute
-
routeには名前をつけることができる
const router = new VueRouter({ routes: [ { path: '/user/:userId', name: 'user', component: User } ] })
-
つけた名前は
<route-link>
あるいは$router.push()
で指定できる<router-link :to="{ name: 'user', params: { userId: 123 }}">User</router-link>
router.push({ name: 'user', params: { userId: 123 }})
リダイレクト
-
リダイレクトを設定できる
const router = new VueRouter({ routes: [ { path: '/a', redirect: '/b' } ] }) // 動的にリダイレクトさせることもできる const router = new VueRouter({ routes: [ { path: '/a', redirect: to => { return '/b' }} ] })
エイリアス
-
エイリアスはリダイレクトと異なり、最初にアクセスしたURLを書き換えない
// /b にアクセスするとURLはそのまま、/a の内容が表示される const router = new VueRouter({ routes: [ { path: '/a', component: A, alias: '/b' } ] })
$route をpropsで渡す
-
this.$route
をコンポーネント内で直接付参照すると、特定のrouteとコンポーネントが密結合してしまう- propsを介してroute固有の情報を受け渡すことで、結合を疎にできる
const User = { // $this.route.params.idを直接参照しなくていいので、その他の方法でIDを渡すこともでできる props: ['id'], template: '<div>User {{ id }}</div>' } const router = new VueRouter({ routes: [ // props設定を有効にすることで、$route.paramsの内容がそのままpropsとして渡る { path: '/user/:id', component: User, props: true }, // Functionで指定することもできる { path: '/user/:id', component: User, props: (route) => (...) }, ] })
HTML5 History
-
routerはhashモードとhistoryモードがある
- hash: デフォルトのモード。内部的なハッシュを使って画面遷移をコントロールする
- history: HTML5のhistoryオブジェクトの機能を利用するモード。hashと同じくページはリロードされないが、URLが書き換わる
const router = new VueRouter({ mode: 'history', routes: [...] })
-
historyモードはユーザが直接URLを叩くと、サーバが対応できずに404になる可能性がある
- 404の場合はルートリダイレクトする、などサーバ側の対処が必要になる