laravelのInertiaで「登録完了しました!」のような一時的なメッセージを表示させたいのですが、どうすればできますか?
laravelにはflash messageという優れた仕組みがあります。Inertiaを使うと利用方法が少し異なるので見ていきましょう!
今回は次の方におススメの内容になります。
- 一時的なメッセージを表示させたい
- 複数の一時的なメッセージを表示させたい
- Inertiaでflash messageを使う方法を知りたい
一時的にメッセージを表示させる裏の仕組みを理解したうえで、実際に利用できるようになります。それでは見ていきましょう!
flash messageとは何か
flash messageとは「セッションにデータを一時保存して、次のページで利用できる仕組み」です。
登録の完了などのステータスメッセージを表示させたい場合に利用します。
セッションはサーバーにデータを保存してブラウザを閉じるまで保存してくれます。
後続のHTTPリクエストの後(次のページが表示されて次にページが読み込まれた後)に一時保存したデータを削除します。
この一連の処理を自動で行ってくれるため、次のページでのみメッセージを表示させたいときに便利です。
Inertiaでflash messageを使う
flash messageを使う流れは次のとおりです。
- flash messageを設定する
- flash messageをVueファイルに渡す
- Vueファイルでflash messageを受け取り表示する
今回はユーザーが完了した時にインフォメーションメッセージを表示させましょう!
flash messageを設定する
スタートはInertiaを導入したところからです。まだの方はこちらから
まずはセッションにメッセージを保存します。ユーザー登録完了し、ログインした後に実装します。
RegisteredUserController.php
public function store(Request $request) { $request->validate([ 'name' => 'required|string|max:255', 'email' => 'required|string|email|max:255|unique:users', 'password' => ['required', 'confirmed', Rules\Password::defaults()], ]); $user = User::create([ 'name' => $request->name, 'email' => $request->email, 'password' => Hash::make($request->password), ]); event(new Registered($user)); Auth::login($user); session()->flash('message', 'ユーザー登録しました。'); return redirect(RouteServiceProvider::HOME); }
「message」をキーにして「ユーザー登録しました」をセッションに保存しています。
Laravelでセッションデータを利用する方法は、グローバルなsessionヘルパとRequestインスタンスの2つあります。
今回は、グローバルなsessionPHP関数を使用して、セッション内のデータを取得/保存しました。
Requestインスタンスを利用して次のように書き換えることもできます。どちらを使用しても差はほとんどありません。
$request->session()->flash('message', 'ユーザー登録しました。');
flash messageをVueファイルに渡す
Vueファイルに値をわたすために、セッションに保存したデータを取得します。
HandleInertiaRequests.php
public function share(Request $request) { return array_merge(parent::share($request), [ 'auth' => [ 'user' => $request->user(), ], 'flash' => [ 'message' => $request->session()->get('message'), ], ]); }
Vueファイルで一律に取得したいデータは、shareメソッドにまとめて記述します。
'flash' => [ 'message' => $request->session()->get('message'), ],
messageというキーでセッションから取得した値(ユーザー登録しました。)を、messageというキーに値としていれています。
親クラスのshareメソッドの戻り値に、ここで設定する値を合体しています。
Middleware.php
public function share(Request $request) { return [ 'errors' => function () use ($request) { return $this->resolveValidationErrors($request); }, ]; }
これで、セッションに保存した値をVueファイルに送る準備ができました。
Vueファイルで値を受け取る
flash messageを受け取るコンポーネントを作成しましょう。
resources/js/Components/FlashMessage.vue
<template> <div v-if="message"> <ul class="flex items-center justify-center bg-gray-600 text-white"> <li>{{ message }}</li> </ul> </div> </template> <script> import {usePage} from "@inertiajs/inertia-vue3"; import {computed} from "vue"; export default { name: "FlashMessage", setup() { const message = computed(() => usePage().props.value.flash.message) return { message, } } } </script> <style scoped> </style>
import {usePage} from "@inertiajs/inertia-vue3";
shareメソッドで設定した値を受け取るために、usePageをインポートします。
const message = computed(() => usePage().props.value.flash.message)
メッセージに変化があった場合に表示させたいので、computedで値を監視して、変化後の値をmessgeで定義しています。
usePage().props.value.で値にアクセスできます。今回はflashキーにあるmessageキーにアクセスしたいので、flash.messageと記述します。
ダッシュボードにflash messageコンポーネントを置きましょう。
resources/js/Pages/Dashboard.vue
<template> <Head title="Dashboard" /> <BreezeAuthenticatedLayout> <template #header> <h2 class="font-semibold text-xl text-gray-800 leading-tight"> Dashboard </h2> </template> <FlashMessage/> ~省略~ </template> <script> import BreezeAuthenticatedLayout from '@/Layouts/Authenticated.vue' import { Head } from '@inertiajs/inertia-vue3'; import FlashMessage from "@/Components/FlashMessage"; export default { components: { FlashMessage, BreezeAuthenticatedLayout, Head, }, } </script>
これで準備は整いましたので、ユーザー登録をしてみましょう!
「ユーザー登録しました。」と表示されれば成功です。
再読み込みしてみましょう。
「ユーザー登録しました。」が消えています。セッションの値が次のHTTPリクエストの後に削除される仕組みだからです。
セッションの理解が深まり、flash messageが使えるようになりました!
それはよかったです!複数のメッセージを表示させる方法もあるので、別の機会に説明しますね
めっちゃ楽しみです!
コメント