Vue.js入門 ―最速で作るシンプルなWebアプリケーション

第4回 シングルページアプリケーションの基礎を作成する

この記事を読むのに必要な時間:およそ 4.5 分

名前付きルート

SPAでページ遷移をさせたい時に,ルートの名前を付けて指定できると便利なことがあります。Vue Routerではルートを定義した時に名前を付与して,その名前を指定してページ遷移を実行できます。

以下,/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.pushを使ったプログラミングによる遷移も可能です。

router.push({ name: 'user', params: { userId: 123 }})

渡される引数は<router-link>to プロパティで受け取るオブジェクト同じものなので,上記のように名前付きルートを使った遷移も可能です。

ネストされたルート

アプリケーションが少し複雑になってくると,ネストされたURLを使って,それに対応したコンポーネントを定義したいケースがあります。たとえば,ユーザ詳細ページの中で,プロフィール情報を表示するコンポーネントと,そのユーザが投稿した情報を表示するコンポーネントの表示を,URLに応じて部分的に切り替えたい時などです。そのようなケースも,Vue Routerを用いると簡単に実現できます。

// ユーザー詳細ページのコンポーネント定義
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/123としてアクセスしたユーザ詳細ページからそれぞれプロフィールページと投稿ページをクリックした際にページ内の該当箇所が部分的に更新されているのがわかります。

なお,今回の連載ではメジャーなブラウザが直接解釈可能な,ECMAScript 5準拠のコードを用いて解説しています。現時点でサポートされるブラウザは少し限られますが,ES2015のTemplate literalを使用してコンポーネントのtemplateを記述すると,より明瞭な記述が可能になります。興味のある方は,Template literalを使ったコード例をご参照ください。

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

状況に応じて,SPAでも通常のWebアプリケーションと同様に,リダイレクトの機能を使用したいケースが出てくることもあるでしょう。Vue Routerは,実行した時にURLを書き換えるリダイレクトと,URLは書き換えずルーティング処理を実行するエイリアスを使用することができます。

リダイレクト

以下のリダイレクトのコード例では,/aへアクセスした時に/bへ遷移します。その時URLも遷移先のものに書き換わります。また,*を使うことで定義している全てのルートにマッチしなかった時のリダイレクト先を指定することもできます。1つの代表的な例として,Not Foundページを作る時に便利です。

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がレンダリングされ,あたかも/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を使った場合,URLの末尾に#/が付与され,ルーティングのパスを管理します。クライアント側でURLが変更されるため,ブラウザの履歴に追加されます。ブラウザの戻る・進むボタンを押した際には,内部的にhashchangeイベントを使ってルーティングの変更時の処理が行われます。

HTML5 History API

もう1つの履歴の管理方法として,HTML5から導入された履歴スタックを操作できるHTML5 History APIがあります。こちらを使った場合,#/は付与されず,URLが通常のサーバサイドで遷移を行った時と同じ形式になります。このモードではユーザが直接ブラウザで該当のURLを入力してアクセスした時に,サーバ側がエラーを起こさずに適切にSPAのページを返す処理をしなくてはならない点に注意が必要です。

Vue RouterはデフォルトでURL Hashとして動作します。'hash'もしくは'history'をVue Routerインスタンス生成時にmodeオプションとして指定することで切り替えることができます。

var router = new VueRouter({
  mode: 'history',
  routes: [...]
})

まとめ

いかがでしたか。一見難しそうに見えるSPAの実装がVue.jsとVue Routerを組み合わせることで簡単に実現できるようになります。次回はVue Routerが提供するデータの取得やフック関数についてなど,SPAを構成するためのもう少し高度な機能と実装例について紹介します。お楽しみに。

著者プロフィール

手島拓也(てじまたくや)

新卒で入社した日本IBM研究所にて検索・テキスト解析ソフトウェア製品の開発に関わったのち,LINE株式会社にて数多くのLINEプラットフォーム開発を担当。その後,株式会社Indieの共同創業者&CTOとしてサービス開発全般を担当。

GitHub:tejitak
Twitter:@tejitak