Vue 3 × モックAPI × 環境変数制御:未納エラーの表示処理テスト構成メモ
📝 概要
業務で担当中の Vue 3 アプリにて、未納エラーをUI上で表示し、「次へ」ボタンを非活性にする処理の実装メモ。
APIはモック(mock-test-api.ts
)で、将来的な切り替えに備えつつ、現時点では環境変数経由でモックAPI関数を指定している。
自分用メモで他人には非公開の想定。
🗂 現状の構成ファイル
src/
├── mock-test-api.ts // モックAPI定義(isNotPaid返す)
├── FrontRepository-test.ts // API呼び出し用リポジトリ
├── BusinessLogic-test.ts // ビジネスロジック:UI状態計算
├── Front-test.vue // UI本体(未納エラー表示・ボタン制御)
├── vite-env.d.ts // import.meta.env の型定義
.env // 環境変数定義(関数名管理)
✅ 使用する環境変数
VITE_API_FUNCTION_NAME=fetchMockStatus
📄 vite-env.d.ts
interface ImportMetaEnv {
readonly VITE_API_FUNCTION_NAME: string;
}
interface ImportMeta {
readonly env: ImportMetaEnv;
}
🔧 モックAPI(mock-test-api.ts)
export function fetchMockStatus(scenario: 'scenarioA' | 'scenarioB' = 'scenarioA') {
let isNotPaid = false;
if (scenario === 'scenarioA') {
isNotPaid = true;
}
return Promise.resolve({ isNotPaid });
}
🔁 リポジトリ(FrontRepository-test.ts)
import * as mockApi from './mock-test-api';
const apiFunctionName = import.meta.env.VITE_API_FUNCTION_NAME || 'fetchMockStatus';
export async function getFrontStatus(scenario: 'scenarioA' | 'scenarioB' = 'scenarioA') {
const fetchFunc = mockApi[apiFunctionName];
if (typeof fetchFunc !== 'function') {
throw new Error(`API関数 "${apiFunctionName}" が見つかりません`);
}
return await fetchFunc(scenario);
}
📐 ビジネスロジック(BusinessLogic-test.ts)
export function getUiState({ isNotPaid, miniFlag = false }) {
const showErrorPanel = isNotPaid || miniFlag;
return {
showErrorPanel,
nextDisabled: showErrorPanel,
backDisabled: false,
};
}
🖥 UIコンポーネント(Front-test.vue)
<template>
<div style="max-width: 400px; margin: 2rem auto; padding: 2rem; border: 1px solid #ccc; border-radius: 8px;">
<h2>テストUI</h2>
<div>
<label><input type="radio" value="scenarioA" v-model="scenario" /> シナリオA: 未納あり</label>
<label style="margin-left: 1rem;"><input type="radio" value="scenarioB" v-model="scenario" /> シナリオB: 未納なし</label>
</div>
<div>
<label><input type="checkbox" v-model="miniFlag" /> miniFlag: 仮会員</label>
</div>
<button @click="fetchStatus">状態取得</button>
<div v-if="uiState.showErrorPanel" style="background: #ffe0e0; padding: 1rem; margin-top: 1rem;">
<div v-if="uiState.isNotPaid">未納エラー</div>
<div v-if="uiState.miniFlag">ミニフラグエラー</div>
</div>
<div style="margin-top: 1rem;">
<button :disabled="uiState.nextDisabled">次へ</button>
<button :disabled="uiState.backDisabled">戻る</button>
</div>
</div>
</template>
<script setup>
import { ref } from 'vue';
import { getFrontStatus } from './FrontRepository-test';
import { getUiState } from './BusinessLogic-test';
const scenario = ref('scenarioA');
const miniFlag = ref(false);
const uiState = ref({
showErrorPanel: false,
nextDisabled: false,
backDisabled: false,
isNotPaid: false,
miniFlag: false
});
async function fetchStatus() {
const res = await getFrontStatus(scenario.value);
uiState.value = {
...getUiState({ isNotPaid: res.isNotPaid, miniFlag: miniFlag.value }),
isNotPaid: res.isNotPaid,
miniFlag: miniFlag.value
};
}
fetchStatus();
</script>
🛠 実装時の進め方メモ(個人向け)
🎯 状況
- mock-test-api.ts と FrontRepository-test.ts は既に用意されていた
- UI・ボタン制御は未実装
- miniFlag の設定はフロントロジック側で管理してよい
✅ 実装順メモ
順番 | 作業 | ファイル |
---|---|---|
① |
getUiState() を作成(isNotPaid / miniFlag → UI状態) |
BusinessLogic-test.ts |
② | Vue内に uiState を定義、取得した状態を格納 |
Front-test.vue |
③ | UIテンプレートにエラーパネルとボタン状態を反映 | Front-test.vue |
④ |
getFrontStatus() を使って状態を取得&更新 |
Front-test.vue |
⑤ | 初期表示時にも fetchStatus() を実行して状態反映 |
Front-test.vue |
📌 注意点メモ
- モックAPIがリポジトリをimportするのはNG設計(依存逆転)
- 環境変数経由で関数名を指定する設計は、将来の切り替えに柔軟で◎
- ロジックとUIは分離(getUiStateでUI状態だけ渡す)