Vue Routerで画面を分ける
複数のURLを一つのSPAで扱うにはVue Routerを使います。公式にサポートされているルーターで、URLと表示するコンポーネントを対応させます。
インストールSHELL
npm install vue-routerrouter/index.jsJAVASCRIPT
import { createRouter, createWebHistory } from 'vue-router'
import HomeView from '../views/HomeView.vue'
import AboutView from '../views/AboutView.vue'
export default createRouter({
history: createWebHistory(),
routes: [
{ path: '/', component: HomeView },
{ path: '/about', component: AboutView }
]
})アプリのルートでapp.use(router)を呼び出し、テンプレートに<RouterLink>と<RouterView>を置きます。サーバー公開時は、直接URLへアクセスしたときも同じSPAへ戻す設定が必要です。
Piniaで共有状態を管理する
ログインユーザー、カート、設定など複数画面から使う状態はPiniaのstoreへまとめられます。まずPropsで渡す方法を検討し、深い階層や複数ページで共有したいときに導入します。
インストールSHELL
npm install piniastores/cart.jsJAVASCRIPT
import { ref, computed } from 'vue'
import { defineStore } from 'pinia'
export const useCartStore = defineStore('cart', () => {
const items = ref([])
const count = computed(() => items.value.length)
function add(item) { items.value.push(item) }
return { items, count, add }
})storeのactionを通して更新すると、どの画面から変更されたか追跡しやすくなります。API通信をstoreに置く場合も、loading、error、成功データを分けて持ちます。
Vitestでロジックをテストする
画面全体をいきなりテストする前に、入力を受けて結果を返す純粋な関数から始めると、テストの考え方を理解しやすくなります。
関数とテストJAVASCRIPT
export function total(items) {
return items.reduce((sum, item) => sum + item.price, 0)
}total.test.jsVITEST
import { expect, test } from 'vitest'
import { total } from './total'
test('商品の合計を求める', () => {
expect(total([{ price: 100 }, { price: 250 }])).toBe(350)
})実行結果OUTPUT
PASS 商品の合計を求めるテストは正常系だけでなく、空配列、0、境界値、不正入力も確認します。コンポーネントテストでは、利用者のクリックや入力を通して画面の振る舞いを検証します。
導入する順序を決める
- まずコンポーネントとComposition APIで小さく作る
- 画面が増えたらVue Routerを追加する
- 共有状態がPropsだけで苦しくなったらPiniaを追加する
- 壊したくない計算・入力・通信状態をテストする
- TypeScript、Lint、Format、CIへ広げる
ライブラリを増やすことが設計ではありません。状態の所有者、データの流れ、失敗時の表示を先に決め、必要な道具だけを選びます。