Vue.js入門 #08 4章 Vue Routerの高度な機能

前 [Vue.js入門 #07 4章 Vue Routerによるシングルページアプリケーション(SPA)](https://qiita.com/tseno/items/2c0417a1b013d786ed84)
次 [Vue.js入門 作成中](https://qiita.com/tseno/items/)


# Vue Routerの高度な機能

## RouterインスタンスとRouteオブジェクト

- `$router`と`$route`について、名前が似ているが別のもの。

### `$router`

- Routerインスタンスを表す。
- RouterインスタンスはWebアプリケーション全体に1つ存在し、全体的なRouter機能を管理している。

|プロパティ／メソッド名|説明|
|:--|:--|
|app|ルーターが使用されているrootのVueインスタンス|
|mode|ルーターのモード（履歴の管理で後述）|
|currentRoute|Routeオブジェクトとして表される現在のルート|
|push(location,onComplete?,onAbort?)|ページ遷移の実行。historyスタックに新しいエントリを追加し、ブラウザの戻るボタンがクリックされた際には前のURLに戻る|
|replace(location,onComplete?,onAbort?)|ページ遷移の実行。historyスタックには新しいエントリを追加しない|
|go(n)|historyスタックの中でどのくらいステップを進めるか、もしくは戻るのかを表す1つのIntegerをパラメーターとして受け取る。Window.history.go(n)に似ている|
|back()|historyスタックを1つ戻す。history.back()と同様|
|forward()|historyスタックを1つ進める。|
|addRoutes(routes)|動的にルートをルータに追加する|

### `$route`

- Routeオブジェクトと呼ばれるもの。
- 現在アクティブなルートの状態を保持したオブジェクトで、現在のパスやURLパラメーターなどの情報を取得できる。
- コンポーネントの内部に実装するRouterのフック関数などからアクセスできる。
- watchの監視対象としても用いる。

|プロパティ名|説明|
|:--|:--|
|path|現在のルートのパスに対応した文字列|
|params|定義したURLパターンにマッチした現在のパラメーターをkey/valueペアで保持するオブジェクト。もしパラメーターが無い場合、この値は空オブジェクトになる|
|query|クエリ文字列のkey/valueペアを保持するオブジェクト。/foo?user=1というパスの場合、$route.query.user==1となる。もしクエリーがない場合は、空オブジェクト|
|hash|URLに#によるハッシュがある時の現在のルートのハッシュ値を取得できる。もしハッシュがない場合は、空オブジェクト|
|fullPath|クエリやhashを含む全体のURL|
|name|名前付きルートで指定された名前|


## ネストしたルーティング

- ルーター定義に`children`を用いると、入れ子となるコンポーネントを定義できる。

```html
<script src="https://unpkg.com/vue@2.5.17"></script>
<script src="https://unpkg.com/vue-router@3.0.1"></script>
<div id="app">
  <router-link to="/user/123">ユーザー123さん</router-link>
  <router-view></router-view>
</div>
```

```js
// ユーザー詳細ページのコンポーネント定義
var User = {
    template:
        '<div class="user">' +
        '<h2>ユーザーIDは {{ $route.params.userId }} です。' +
        '<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: [
                {
                    path: 'profile',
                    component: UserProfile
                },
                {
                    path: 'posts',
                    component: UserPosts
                }
            ]
        }
    ]
})

var app = new Vue({
    router: router
}).$mount('#app')
```

- 初期状態

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/d6e1b240-3872-a5f2-f4e1-6b37023ff248.png)

- ユーザー123さんをクリックすると、コンポーネントUserが表示され、さらにプロフィールページを見るをクリックすると、UserProficeコンポーネントが表示される。

![image.png](https://qiita-image-store.s3.amazonaws.com/0/88686/a00179a1-9e33-4afb-2eb8-dcd1e7c9dd8e.png)



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

### リダイレクト

- 以下のコード例では、`/a`にアクセスした時、`/b`にリダイレクトされる。
- いずれにもマッチしなかった場合、`/notfound`にリダイレクトされる。

```js
var router = new VueRouter({
  routes: [
    { path: '/a', redirect: '/b' },
    { path: '/b', component: B },
    { path: '/notfound', component: NotFound },
    // いずれにもマッチしなかった場合
    { path: '*', redirect: '/notfound' },
  ]
})


```

### エイリアス

- 以下はエイリアスの例。`/b`にアクセスしたときに、`/a`にアクセスしたかのように振る舞い、コンポーネントAがレンダリングされる。
- 2つめの例は、エイリアスを複数指定している。

```js
var router = new VueRouter({
  routes: [
    { path: '/a', component: A, alias: '/b' },
    { path: '/c', component: C, alias: ['/d','/e'] }
  ]
})
```

## 履歴の管理

- SPAではサーバー側のルーティングを介していないため、クライアント側で履歴管理しなくてはならない。

### URL Hash

- URL Hashを使った場合、URLの末尾に`#/`が付与され、ルーティングのパスを管理する。Vue Routerではデフォルト。
- 直接ブラウザのURLを入力しても、特に処理を工夫しなくても良い。

### HTML5 History API

- HTML5から導入された履歴スタックを操作できるHTML5 History APIがある。
- URLの末尾に`#/`が付与されない。直接URLを入力した時に、エラーを起こさず適切にSPAのページを返す処理をしなくてはならない。
- `history`をVue Routerインスタンス生成時にmodeオプションとして指定することで切り替えられる。

#### Vue Routerを使った大規模なアプリケーションの実装

- Vue RouterもVuexも使わないアプリケーション
    - 従来型のECサイトのようなサーバー側でルーティングを行い、クライアント側では複雑なコンポーネント構成を持たないアプリケーション
    - サービス紹介サイトなど、一部動的に動くコンポーネント実装が必要なランディングページ（一枚の長いWebページ）
- Vue Routerのみ使うアプリケーション
    - シングルページアプリケーション(SPA)ベースの管理画面など、各ページでシンプルな機能を提供するアプリケーション
    - ネイティブアプリのようにクライアント側で軽快に動くアプリケーション
- Vuexのみつかうアプリケーション
    - ダッシュボード、チャット、写真加工アプリなど、1つのページ内で複数のコンポーネント間のデータ連携が必要になる、単一ツールのようなアプリケーション
- Vue RouterとVuex両方使うアプリケーション
    - メール、カレンダーアプリなど、複数ページで複数コンポーネント構成が想定されるアプリケーション
   



参考
[Vue.js入門 基礎から実践アプリケーション開発まで](https://www.amazon.co.jp/dp/B07J6FP6NQ/ref=dp-kindle-redirect?_encoding=UTF8&btkr=1)