はじめに
この記事は、Laravel + Vue + Inertia.jsを使って家計簿アプリを作成する過程で学んだことをまとめた備忘録です。
- データベースから取得したデータの表示
- 削除機能(ボタンコンポーネント化)
- SweetArler2を使った確認ダイアログとトースト通知
といった、フロントとバックエンドの連携方法について解説します。
データベースの内容を画面に表示する
Dashboard.vue
Inertia経由で取得した支出データ(expenses
)を一覧表示。フォームで新規登録もできます。
<script setup>
import { Head, useForm } from '@inertiajs/vue3';
import AuthenticatedLayout from '@/Layouts/AuthenticatedLayout.vue';
import InputLabel from '@/Components/InputLabel.vue';
import TextInput from '@/Components/TextInput.vue';
import PrimaryButton from '@/Components/PrimaryButton.vue';
import InputError from '@/Components/InputError.vue';
const props = defineProps({ expenses: Array });
const form = useForm({
amount: '',
date: '',
title: '',
category: '',
});
const submit = () => {
form.post(route('expenses.store'), {
onSuccess: () => form.reset(),
});
};
</script>
<template>
<AuthenticatedLayout>
<!-- フォーム -->
<form @submit.prevent="submit">
<!-- 各入力欄 -->
<!-- ...省略... -->
<PrimaryButton class="mt-4">登録</PrimaryButton>
</form>
<!-- 一覧表示 -->
<table>
<thead>
<tr>
<th>日付</th><th>金額</th><th>費用名</th><th>カテゴリー</th>
</tr>
</thead>
<tbody>
<tr v-for="expense in expenses" :key="expense.id">
<td>{{ expense.date }}</td>
<td>{{ expense.amount }}</td>
<td>{{ expense.title }}</td>
<td>{{ expense.category }}</td>
</tr>
</tbody>
</table>
</AuthenticatedLayout>
</template>
削除機能の実装(コンポーネント化)
1. ルート設定(web.php
)
Route::middleware(['auth'])->group(function () {
Route::get('/dashboard', [DashboardController::class, 'index'])->name('dashboard');
Route::post('/expenses', [DashboardController::class, 'store'])->name('expenses.store');
Route::delete('/expenses/{expense}', [DashboardController::class, 'destroy'])->name('expenses.destroy');
});
2. コントローラーに削除処理追加
public function destroy(Expense $expense)
{
if(auth()->id() !== $expense->user_id) {
abort(403);
}
$expense->delete();
return redirect()->route('dashboard')->with('message', '削除しました');
}
3. 削除ボタンコンポーネントを作成
resources/js/Components/DeleteButton.vue
<script setup>
import { router } from '@inertiajs/vue3';
const props = defineProps({ expenseId: Number });
const destroy = () => {
if (confirm('本当に削除しますか?')) {
router.delete(route('expenses.destroy', props.expenseId), {
onSuccess: () => router.reload(),
});
}
};
</script>
<template>
<button @click="destroy" class="bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600">
削除
</button>
</template>
4. Dashboard.vue
で使用
<script setup>
import DeleteButton from '@/Components/DeleteButton.vue';
</script>
<!-- 表示部分 -->
<tr v-for="expense in expenses" :key="expense.id">
<td>{{ expense.date }}</td>
<td>{{ expense.amount }}</td>
<td>{{ expense.title }}</td>
<td>{{ expense.category }}</td>
<td><DeleteButton :expense-id="expense.id" /></td>
</tr>
SweetAlert2の導入&削除時確認ダイアログ
1. インストール
npm install sweetalert2
# Laravel Sailの場合:
./vendor/bin/sail npm install sweetalert2
2. DeleteButton.vue
に組み込み
<script setup>
import { router } from '@inertiajs/vue3';
import Swal from 'sweetalert2';
const props = defineProps({ expenseId: Number });
const destroy = () => {
Swal.fire({
title: '本当に削除しますか?',
text: 'この操作は取り消せません!',
icon: 'warning',
showCancelButton: true,
confirmButtonColor: '#d33',
cancelButtonColor: '#3085d6',
confirmButtonText: '削除する',
cancelButtonText: 'キャンセル',
}).then((result) => {
if (result.isConfirmed) {
router.delete(route('expenses.destroy', props.expenseId), {
onSuccess: () => {
router.reload();
Swal.fire('削除しました', 'データは正常に削除されました。', 'success');
},
});
}
});
};
</script>
SweerAlert2でトースト通知(登録完了メッセージなど)
1. Controllerでフラッシュメッセージを設定
return redirect()->route('dashboard')->with('message', '登録しました');
2. HandleInertiaRequests.php
で共有
public function share(Request $request): array
{
return array_merge(parent::share($request), [
'flash' => [
'message' => fn () => $request->session()->get('message'),
],
]);
}
3. Dashboard.vue
でトースト表示
<script setup>
import Swal from 'sweetalert2';
import { usePage } from '@inertiajs/vue3';
import { watch } from 'vue';
const page = usePage();
watch(() => page.props.flash?.message, (message) => {
if (message) {
Swal.fire({
toast: true,
position: 'top-end',
icon: 'success',
title: message,
showConfirmButton: false,
timer: 2000,
timerProgressBar: true,
});
}
});
</script>
おわりに
- データベースの保存
- 削除処理(確認つき・非同期)
- トースト通知の実装
以上の内容を通して、Inertia.js + Vue.js + Laravelの連携方法が少しでも理解できたなら幸いです。