TechVue.jsJapanese

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

Tech

本記事では Vue3 プロジェクト で Bootstrap 5 画面遷移 を 実装 する方法について紹介していきます。今回は Bootstrap5 の Button を用いて、 3 つの 画面を用いた 画面遷移 の サンプル プログラム を作成する形で、 進めていきます。 最終的に作成する サンプル アプリケーション の 動作 は以下のようになります。

Screen transition flow

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

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

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


プロジェクト に Bootstrap コンポーネント を作成

[ads]

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

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


Menu Button (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.vueOption.vue を作成していきます。いずれも views ディレクトリ の配下に作成していきます。


Display Menu Button (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>

戻る Button (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>

ルーティング 情報の準備

[ads]

コンポーネント の作成ができたところで、これらの コンポーネント を結びつける ルーティング の情報を作成していきます。まずは、 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>

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


アプリの実行

[ads]

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

それでは、各 ボタン を クリック したときの動作をみていきます。 以下の通り、 狙った通りの画面遷移が実装できていることを 確認 することができます。


まとめ

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

関連記事


[ads]

今回使用したコード

Project src directory

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 directory

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 directory

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>

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>

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>
Ads