はじめに
この連載の前回までの記事で解説にあったように、
シングルページアプリケーションとは
シングルページアプリケーション
一般的にSPAを実装するには、
Vue Routerの基礎
ルーターのインストール
Vue.
<script src="https://cdn.jsdelivr.net/vue/2.0.3/vue.min.js"></script>
<script src="https://cdn.jsdelivr.net/vue.router/2.0.1/vue-router.min.js"></script>
ルートの定義
ルートとは、routes
オプションに設定されます。
// ルートオプションを渡してルーターインスタンスを生成します
var router = new VueRouter({
// 各ルートにコンポーネントをマッピングします
// コンポーネントはVue.extend() によって作られたコンポーネントコンストラクタでも
// コンポーネントオプションのオブジェクトでも構いません
routes: [
{
path: '/top',
component: {
template: '<div>トップページです。</div>'
}
},
{
path: '/users',
component: {
template: '<div>ユーザー一覧ページです。</div>'
}
}
]
})
// ルーターのインスタンスをrootとなるVueインスタンスに渡します
var app = new Vue({
router: router
}).$mount('#app')
これだけで基本的なルートの定義は完了です。
SPAを実装していると、path
内のURLに:
を使用してパターンを記述しましょう。マッチしたURL上のパラメータはコンポーネント内の$route.
からパターンに使用したパラメータ名と同じ名前でアクセスして取得することができます。
たとえば、/user/:userId
というURLで受け付けて、/user/
へアクセスがあった時に、$route.
の値は123
になります。
var router = new VueRouter({
routes: [
{
// コロンで始まるパターンマッチング
path: '/user/:userId',
component: {
template: '<div>ユーザーIDは {{ $route.params.userId }} です。</div>'
}
}
]
})
ページ遷移の実行
URLがマッチした時にマッピングされたコンポーネントをレンダリングして出力する先をrootのVueインスタンスがマウントしているHTML内に指定しましょう。<router-view>
タグを使用します。
<div id="app">
<!-- 現在のURLとマッチしたルートに定義されたコンポーネントがここにレンダリングされます -->
<router-view></router-view>
</div>
この例ではブラウザで直接入力してアクセスしたURLとルート内でマッピングしたコンポーネントが<router-view>
の部分にレンダリングされます。ただし、
<div id="app">
<!-- リンク先を `to` プロパティに指定します -->
<!-- デフォルトで <router-link> は `<a>` タグとしてレンダリングされます -->
<router-link to="/top">トップページ</router-link>
<router-link to="/users">ユーザー一覧ページ</router-link>
<router-view></router-view>
</div>
jsfiddleのサンプルを実行してみてください
以上、
名前付きルート
SPAでページ遷移をさせたい時に、
以下、/user/:userId
というpath
に名前をつけてルートを定義する例です。
var router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: {
template: '<div>ユーザーIDは {{ $route.params.userId }} です。</div>'
}
}
]
})
上記の名前付きルートを呼び出すには、<router-link>
のto
パラメータに指定します。同時にURLパターンへのパラメータも同時に渡すことができます。
<router-link :to="{ name: 'user', params: { userId: 123 }}">ユーザー詳細ページ</router-link>
router.pushを使った遷移
上で紹介したhtml内の宣言的な書き方である<router-link>
の代わりに、router.
を使ったプログラミングによる遷移も可能です。
router.push({ name: 'user', params: { userId: 123 }})
渡される引数は<router-link>
の to
プロパティで受け取るオブジェクト同じものなので、
ネストされたルート
アプリケーションが少し複雑になってくると、
// ユーザー詳細ページのコンポーネント定義
var User = {
template:
'<div class="user">' +
'<h2>ユーザーIDは {{ $route.params.userId }} です。</h2>' +
'<router-link :to="\'/user/\' + $route.params.userId + \'/profile\'">ユーザーのプロフィールページを見る</router-link>' +
'<router-link :to="\'/user/\' + $route.params.userId + \'/posts\'">ユーザーの投稿ページを見る</router-link>' +
'<router-view></router-view>' +
'</div>'
}
// ユーザー詳細ページ内で部分的に表示されるユーザーのプロフィールページ
var UserProfile = {
template:
'<div class="user-profile">' +
'<h3>こちらはユーザー {{ $route.params.userId }} のプロフィールページです。</h3>' +
'</div>'
}
// ユーザー詳細ページ内で部分的に表示されるユーザーの投稿ページ
var UserPosts = {
template:
'<div class="user-posts">' +
'<h3>こちらはユーザー {{ $route.params.userId }} の投稿ページです。</h3>' +
'</div>'
}
var router = new VueRouter({
routes: [
{
path: '/user/:userId',
name: 'user',
component: User,
children: [
{
// /user/:userId/profile がマッチした時に
// UserProfileコンポーネントはUserコンポーネントの <router-view> 内部でレンダリングされます
path: 'profile',
component: UserProfile
},
{
// /user/:userId/posts がマッチした時に
// UserPostsコンポーネントはUserコンポーネントの <router-view> 内部でレンダリングされます
path: 'posts',
component: UserPosts
}
]
}
]
})
こちらのjsfiddleが動作する例です。/user/
としてアクセスしたユーザ詳細ページからそれぞれプロフィールページと投稿ページをクリックした際にページ内の該当箇所が部分的に更新されているのがわかります。
なお、template
を記述すると、
リダイレクトとエイリアス
状況に応じて、
リダイレクト
以下のリダイレクトのコード例では、/a
へアクセスした時に/b
へ遷移します。その時URLも遷移先のものに書き換わります。また、*
を使うことで定義している全てのルートにマッチしなかった時のリダイレクト先を指定することもできます。1つの代表的な例として、
var router = new VueRouter({
routes: [
{ path: '/a', redirect: '/b' },
{ path: '/b', component: B },
{ path: '/notfound', component: NotFound },
// 現在のURLが定義したルートのいずれにもマッチしなかった時に/notfoundに遷移する
{ path: '*', redirect: '/notfound' }
]
})
エイリアス
URL上はアクセスした時のものを保持した状態で、alias
が使えます。以下の1つめの例では、/b
へアクセスした時にURL上は/b
のままですが、/a
へアクセスしたかのように振る舞います。2つめの例のようにaliasは複数指定することもできます。
var router = new VueRouter({
routes: [
{ path: '/a', component: A, alias: '/b' }
{ path: '/c', component: C, alias: ['/d', '/e'] }
]
})
履歴の管理
SPAではサーバ側のルーティングを介していないため、URL Hash
を使った方法とHTML5 History API
を使った方法があります。
URL Hash
URL Hash
を使った場合、#/
が付与され、hashchange
イベントを使ってルーティングの変更時の処理が行われます。
HTML5 History API
もう1つの履歴の管理方法として、HTML5 History API
があります。こちらを使った場合、#/
は付与されず、
Vue RouterはデフォルトでURL Hash
として動作します。'hash'もしくは'history'をVue Routerインスタンス生成時にmode
オプションとして指定することで切り替えることができます。
var router = new VueRouter({
mode: 'history',
routes: [...]
})
まとめ
いかがでしたか。一見難しそうに見えるSPAの実装がVue.