VueJS 速習チュートリアル

Vue ルーティング

Vue におけるルーティング(Routing)は、Vue アプリケーション内をナビゲートするために使用されます。これはサーバーを介さずクライアントサイド(ブラウザ)で実行されるため、フルページリロードが発生せず、非常に高速なユーザー体験を実現できます。

ルーティングは、以前学習したダイナミックコンポーネントを使用した切り替えと似た概念のナビゲーション手法です。
ルーティングを導入することで、URL アドレスを使用してアプリケーション内の特定の場所へユーザーを直接誘導できるようになります。

1. ダイナミックコンポーネントによるナビゲーション

Vue のルーティングを理解するために、まずは 2 つのコンポーネントをボタンで切り替えるダイナミックコンポーネントを使用したアプリケーションを見てみましょう。

1.1 実装例

FoodItems.vue:

<template>
    <h1>食べ物!</h1>
    <p>私はほとんどの種類の食べ物が好きです。</p>
</template>

AnimalCollection.vue:

<template>
    <h1>動物!</h1>
    <p>毎年、少なくとも 1 つは新しい動物について学びたいと思っています。</p>
</template>

App.vue:

<template>
  <p>このページの表示したいセクションを選択してください:</p>
  <button @click="activeComp = 'animal-collection'">動物</button>
  <button @click="activeComp = 'food-items'">食べ物</button><br>
  <div>
    <component :is="activeComp"></component>
  </div>
</template>

<script>
export default {
  data() {
      return {
        activeComp: ''
      }
    }
}
</script>

<style scoped>
  button {
    padding: 5px;
    margin: 10px;
  }
  div {
    border: dashed black 1px;
    padding: 20px;
    margin: 10px;
    display: inline-block;
  }
</style>

2. ダイナミックコンポーネントからルーティングへ

Vue では SPA(シングルページアプリケーション) を構築するため、アプリケーションには *.html ファイルが 1 つしか含まれません。そのため、他の *.html ファイルにリンクして異なるコンテンツを表示するという手法は使えません。

上記のダイナミックコンポーネントの例では、ページ内のコンテンツを切り替えることはできますが、特定のセクション(例:食べ物のセクション)へ直接アクセスするための URL アドレスを他の人に共有することはできません。

ルーティングを適切に設定すれば、URL アドレスの末尾に /food-items などを付けることで、そのコンテンツが表示された状態でアプリケーションを直接開くことができるようになります。

3. Vue Router ライブラリのインストール

Vue でルーティング機能を使用するには、ターミナルでプロジェクトフォルダに移動し、Vue Router ライブラリをインストールします。

npm install vue-router@4

4. main.js の更新

ルーティングを使用するには、ルーター(Router) インスタンスを作成する必要があります。通常、これは main.js ファイルで行います。

main.js:

import { createApp } from 'vue'
import { createRouter, createWebHistory } from 'vue-router'
import App from './App.vue'
import FoodItems from './components/FoodItems.vue'
import AnimalCollection from './components/AnimalCollection.vue'

// ルーターの設定
const router = createRouter({
    history: createWebHistory(),
    routes: [
        { path: '/animals', component: AnimalCollection },
        { path: '/food', component: FoodItems },
    ]
});

const app = createApp(App)

// ルーターの使用を宣言
app.use(router);

// ルーターの routes 内で定義されているため、これら 2 行は削除可能です
// app.component('food-items', FoodItems);
// app.component('animal-collection', AnimalCollection);

app.mount('#app')

この設定により、URL の末尾に /animals が付いた場合に AnimalCollection コンポーネントを開くルーターが作成されました。ただし、次に説明する <router-view> コンポーネントを追加するまで、画面には何も表示されません。また、このルーターはブラウザのヒストリー(Web History)を管理するため、ブラウザの「戻る」「進む」ボタンも機能するようになります。

5.  コンポーネントの使用

新しいルーターでページコンテンツを切り替えるには、以前の例で使用していたダイナミックコンポーネントを削除し、代わりに <router-view> コンポーネントを使用します。

App.vue:

<template>
  <p>このページの表示したいセクションを選択してください:</p>
  <button @click="activeComp = 'animal-collection'">動物</button>
  <button @click="activeComp = 'food-items'">食べ物</button><br>
  <div>
    <router-view></router-view>
  </div>
</template>

この変更を適用した後、ブラウザで URL の末尾に /food を手動で入力すると、ページが更新されて食べ物のコンテンツが表示されるようになります。

6.  コンポーネントの使用

ボタンの代わりに、ルーターとより親和性の高い <router-link> コンポーネントを使用します。
これにより activeComp などのデータプロパティが不要になるため、<script> タグを完全に削除、あるいは空にすることができます。

App.vue:

<template>
  <p>このページの表示したいセクションを選択してください:</p>
  <router-link to="/animals">動物</router-link>
  <router-link to="/food">食べ物</router-link><br>
  <div>
    <router-view></router-view>
  </div>
</template>

<script>
// ロジックが不要になったため、空の export default
export default {}
</script>

7.  コンポーネントのスタイリング

ブラウザで要素を「検証」すると分かりますが、<router-link> コンポーネントは最終的に <a> タグとしてレンダリングされます。

また、Vue はどのコンポーネントがアクティブであるかを自動的に追跡し、現在アクティブなルートに対応する <router-link><a> タグ)に対して .router-link-active というクラスを付与します。

この仕組みを利用して、アクティブなリンクを強調するためのスタイルを適用できます。

7.1 実装例

App.vue:

<template>
  <p>このページの表示したいセクションを選択してください:</p>
  <router-link to="/animals">動物</router-link>
  <router-link to="/food">食べ物</router-link><br>
  <div>
    <router-view></router-view>
  </div>
</template>

<style scoped>
  a {
    display: inline-block;
    background-color: black;
    border: solid 1px black;
    color: white;
    padding: 5px;
    margin: 10px;
    text-decoration: none;
  }

  /* ホバー時およびアクティブなリンクのスタイル */
  a:hover,
  a.router-link-active {
    background-color: rgb(110, 79, 13);
  }

  div {
    border: dashed black 1px;
    padding: 20px;
    margin: 10px;
    display: inline-block;
  }
</style>

       注意: 上記のオンラインエディタの例では URL 自体は更新されない場合がありますが、自身のローカル環境で実行すれば、クリックするたびに URL が /animals/food に更新されることが確認できます。オンライン例で URL が変わらなくても動作するのは、Vue Router が内部的にルーティングを処理しているためです。