Inertiaでのサーバーサイドバリデーションエラーの処理は、`422`レスポンスからバリデーションエラーをキャッチし、フォームのエラー状態を手動で更新する必要がある従来のXHR駆動型フォームとは異なり動作します。これは、Inertiaが`422`レスポンスを受け取らないためです。代わりに、Inertiaは標準のフルページフォーム送信のように動作します。方法は次のとおりです。
まず、Inertiaを使用してフォームを送信します。サーバーサイドのバリデーションエラーがある場合、これらのエラーを`422` JSONレスポンスとして返しません。代わりに、ユーザーを(サーバーサイドで)以前のフォームページにリダイレクトし、セッションにバリデーションエラーをフラッシュします。Laravelなど、一部のフレームワークでは、これが自動的に行われます。
次に、これらのバリデーションエラーがセッションに存在する場合、それらは自動的にInertiaと共有され、クライアントサイドでページプロパティとして使用できるようになり、フォームに表示できます。プロパティはリアクティブであるため、フォームの送信が完了すると自動的に表示されます。
最後に、Inertiaアプリは`422`レスポンスを生成しないため、Inertiaはレスポンスにバリデーションエラーが含まれているかどうかを判断する別の方法が必要です。これを行うために、Inertiaは`page.props.errors`オブジェクトにエラーが存在するかどうかをチェックします。エラーが存在する場合、リクエストの`onError()`コールバックが`onSuccess()`コールバックの代わりに呼び出されます。
サーバーサイドのバリデーションエラーをクライアントサイドで使用できるようにするには、サーバーサイドフレームワークが`errors`プロパティを介してそれらを共有する必要があります。LaravelアダプターなどのInertiaのファーストパーティアダプターは、これを自動的に行います。他のフレームワークでは、手動で行う必要がある場合があります。詳細については、特定のサーバーサイドアダプターのドキュメントを参照してください。
バリデーションエラーは、クライアントサイドでページコンポーネントのプロパティとして使用できるため、存在に基づいて条件付きで表示できます。ファーストパーティサーバーアダプター(Laravelアダプターなど)を使用する場合、`errors`プロパティは自動的にページで使用できるようになります。
<script setup>
import { reactive } from 'vue'
import { router } from '@inertiajs/vue3'
defineProps({ errors: Object })
const form = reactive({
first_name: null,
last_name: null,
email: null,
})
function submit() {
router.post('/users', form)
}
</script>
<template>
<form @submit.prevent="submit">
<label for="first_name">First name:</label>
<input id="first_name" v-model="form.first_name" />
<div v-if="errors.first_name">{{ errors.first_name }}</div>
<label for="last_name">Last name:</label>
<input id="last_name" v-model="form.last_name" />
<div v-if="errors.last_name">{{ errors.last_name }}</div>
<label for="email">Email:</label>
<input id="email" v-model="form.email" />
<div v-if="errors.email">{{ errors.email }}</div>
<button type="submit">Submit</button>
</form>
</template>
Inertiaでのエラー処理はフルページフォーム送信に似ていますが、Inertiaはさらに多くの利点を提供します。実際、古いフォーム入力データを手動で再入力する必要さえありません。
バリデーションエラーが発生した場合、ユーザーは通常、以前のフォームページにリダイレクトされます。また、デフォルトでは、Inertiaは自動的に コンポーネントの状態を`post`、`put`、 `patch`、および`delete`リクエストに対して保持します。したがって、すべての古いフォーム入力データは、ユーザーがフォームを送信したときとまったく同じままです。
そのため、残りの作業は、`errors`プロパティを使用してバリデーションエラーを表示することだけです。
複数のフォームがあるページの場合、2つのフォームが同じフィールド名を共有している場合、バリデーションエラーを表示するときに競合が発生する可能性があります。たとえば、`name`フィールドを持つ「会社作成」フォームと「ユーザー作成」フォームがあるとします。両方のフォームは`page.props.errors.name`バリデーションエラーを表示するため、いずれかのフォームの`name`フィールドでバリデーションエラーが発生すると、両方のフォームにエラーが表示されます。 `page.props.errors.name`フィールドのバリデーションエラーを生成すると、両方のフォームにエラーが表示されます。
この問題を解決するには、「エラーバッグ」を使用できます。エラーバッグは、サーバーから返されたバリデーションエラーを、そのフォームに固有のキーでスコープします。上記の例を続けると、最初のフォームには`createCompany`エラーバッグがあり、2番目のフォームには`createUser`エラーバッグがある場合があります。 `createCompany`エラーバッグと`createUser`エラーバッグがあります.
import { router } from '@inertiajs/vue3'
router.post('/companies', data, {
errorBag: 'createCompany',
})
router.post('/users', data, {
errorBag: 'createUser',
})
エラーバッグを指定すると、バリデーションエラーはサーバーから`page.props.errors.createCompany`および`page.props.errors.createUser`内で返されます。 `page.props.errors.createCompany`と`page.props.errors.createUser`内で返されます。