[Vue3] Vue CLI で作成したプロジェクトでボタンによる “画面遷移” を実装する方法

Vue CLI ( Vue3 ) プロジェクトにおいて、 Bootstrap Button を用いた “画面遷移” を実現するルーティングを実装する方法を紹介します。実現する画面遷移イメージは以下の通りです。

本記事では以下の条件で進めていきます。

  • Vue CLI で Vue3 プロジェクトとして作成
  • Bootstrap が利用可能な状態
  • Vue Router をプラグインとして利用可能な状態

これらについては、以下の記事も参考にしてください。

コンポーネントの準備

それでは、必要なコンポーネントを用意していきます。以下のように、実現したいアプリのそれぞれのコンポーネントに対応する形でファイルを用意します。カッコ内は、アプリケーションの相対パスを記載しています。アプリが http://localhost:8080/ で動作している場合、 開始画面は http://localhost:8080/start でアクセスできるようにする、ということです。

まずは、呼出し元となる Menu.vue を作成していきます。views ディレクトリの配下に作成していきます。

views / Menu.vue

Menu.vue では、Start, Menu それぞれへのリンクを Bootstrap のボタンを用いて実装していきます。ボタンはリンクを有効にするため、 a タグで記載している点に注意してください。

<template>
 <div class="menu">
   <h1>Select Menu</h1>
   <div class="d-grid gap-2 col-6 mx-auto">
     <a class="btn btn-primary btn-lg" href="/start" role="button">Start</a>
     <a class="btn btn-secondary btn-lg" href="/option" role="button">Option</a>
   </div>
 </div>
</template>

続いて呼出し先である Start.vue と Option.vue を作成していきます。いずれも views ディレクトリの配下に作成していきます。

views / Start.vue

Start.vue では、ロゴの表示と “Menu へ戻る” ボタンを実装します。

<template>
 <div>
   <h1>Start App!</h1>
   <img src="../assets/logo.png" alt="Vue logo">
   <div class="d-grid gap-2 col-2 d-md-block">
     <a class="btn btn-dark" href="/" role="button">Menu</a>
   </div>
 </div>
</template>

views / Option.vue

Option.vue ではオプションをリスト表示し、 “Menu へ戻る” ボタンを実装します。

<template>
 <div>
   <h1>Select your Option here</h1>
   <li>Option 1</li>
   <li>Option 2</li>
   <li>Option 3</li>
   <li>Option 4</li>
   <div class="d-grid gap-2 col-2 d-md-block">
     <a class="btn btn-dark" href="/" type="button">Menu</a>
   </div>
 </div>
</template>

ルーティング情報の準備

コンポーネントの作成ができたところで、これらのコンポーネントを結びつけるルーティングの情報を作成していきます。まずは、 router ディレクトリ配下の index.js に各コンポーネントのパスを定義していきます。

router / index.js (抜粋)

routes 変数に各コンポーネントのパスを定義していきます。ルートとなる Menu に関しては忘れずに import し、ルート以外の部分はこのように記載することで、呼び出されたタイミングではじめて読み込まれるため、コンポーネントが多くなった場合でもルートコンポーネントの呼出し速度に影響を与えないことが可能になります。

import Menu from '../views/Menu.vue'
 
const routes = [{
   path: '/',
   name: 'Menu',
   component: Menu
 },
 {
   path: '/start',
   name: 'Start',
   // route level code-splitting
   // this generates a separate chunk (about.[hash].js) for this route
   // which is lazy-loaded when the route is visited.
   component: () => import( /* webpackChunkName: "about" */ '../views/Start.vue')
 },
 {
   path: '/option',
   name: 'Option',
   component: () => import( /* webpackChunkName: "about" */ '../views/Option.vue')
 }
 
]

App.vue

App.vue は以下のとおりです。パラメータなしで router-view を呼び出すことで、デフォルトの View (ここでは、Menu.vue )が呼び出されます。

参考:公式ドキュメント(Named Views)

<template>
 <router-view/>
</template>

なお、上記ですが、以下のように記載しても同じ動作となります。

<template>
 <router-view name="default" />
</template>

それでは、準備が整ったところで早速実行してみます。

アプリの実行

起動すると、Menu.vue で実装したとおり以下の画面が表示されます。

それでは、各ボタンをクリックしたときの動作をみていきます。

まとめ

  • a タグで記載することで Bootstrap Button でリンクが有効になる
  • router / index.js でコンポーネントごとのルーティング情報を記載
  • App.vue に記載する router-view は name を省略すると name=”default” と同じ動作

関連記事

今回使ったコード

main.js

import {
   createApp
} from 'vue'
import App from './App.vue'
import router from './router'
 
import "bootstrap/dist/css/bootstrap.min.css"
 
createApp(App).use(router).mount('#app')

App.vue

<template>
 <router-view/>
</template>
<style>
#app {
 font-family: Avenir, Helvetica, Arial, sans-serif;
 -webkit-font-smoothing: antialiased;
 -moz-osx-font-smoothing: grayscale;
 text-align: center;
 color: #2c3e50;
}
 
#nav {
 padding: 30px;
}
 
#nav a {
 font-weight: bold;
 color: #2c3e50;
}
 
#nav a.router-link-exact-active {
 color: #42b983;
}
</style>

router / index.js

import {
 createRouter,
 createWebHistory
} from 'vue-router'
import Menu from '../views/Menu.vue'
 
const routes = [{
   path: '/',
   name: 'Menu',
   component: Menu
 },
 {
   path: '/start',
   name: 'Start',
   // route level code-splitting
   // this generates a separate chunk (about.[hash].js) for this route
   // which is lazy-loaded when the route is visited.
   component: () => import( /* webpackChunkName: "about" */ '../views/Start.vue')
 },
 {
   path: '/option',
   name: 'Option',
   component: () => import( /* webpackChunkName: "about" */ '../views/Option.vue')
 }
 
]
 
const router = createRouter({
 history: createWebHistory(process.env.BASE_URL),
 routes
})
 
export default router

views / Menu.vue

<template>
 <div class="menu">
   <h1>Select Menu</h1>
   <div class="d-grid gap-2 col-6 mx-auto">
     <a class="btn btn-primary btn-lg" href="/start" role="button">Start</a>
     <a class="btn btn-secondary btn-lg" href="/option" role="button">Option</a>
   </div>
 </div>
</template>

views / Start.vue

<template>
 <div>
   <h1>Start App!</h1>
   <img src="../assets/logo.png" alt="Vue logo">
   <div class="d-grid gap-2 col-2 d-md-block">
     <a class="btn btn-dark" href="/" role="button">Menu</a>
   </div>
 </div>
</template>

views / Option.vue

<template>
 <div>
   <h1>Select your Option here</h1>
   <li>Option 1</li>
   <li>Option 2</li>
   <li>Option 3</li>
   <li>Option 4</li>
   <div class="d-grid gap-2 col-2 d-md-block">
     <a class="btn btn-dark" href="/" type="button">Menu</a>
   </div>
 </div>
</template>