在 Inertia 中处理服务器端验证错误的方式与传统的 XHR 驱动的表单不同,后者需要您从 422
响应中捕获验证错误并手动更新表单的错误状态 - 因为 Inertia 从未收到 422
响应。相反,Inertia 的操作更像标准的全页面表单提交。以下是操作方式
首先,您 使用 Inertia 提交您的表单。如果存在服务器端验证错误,您不会将这些错误作为 422
JSON 响应返回。相反,您将(服务器端)将用户重定向回他们之前所在的表单页面,并将验证错误闪存到会话中。一些框架,例如 Laravel,会自动执行此操作。
接下来,只要这些验证错误存在于会话中,它们就会自动与 Inertia 共享,使其作为页面道具在客户端可用,您可以在表单中显示它们。由于道具是响应式的,因此在表单提交完成后会自动显示它们。
最后,由于 Inertia 应用程序从不生成 422
响应,因此 Inertia 需要另一种方法来确定响应是否包含验证错误。为此,Inertia 检查 page.props.errors
对象中是否存在任何错误。如果存在错误,则请求的 onError()
回调将被调用,而不是 onSuccess()
回调。
为了使您的服务器端验证错误在客户端可用,您的服务器端框架必须通过 errors
道具共享它们。Inertia 的第一方适配器,例如 Laravel 适配器,会自动执行此操作。对于其他框架,您可能需要手动执行此操作。有关更多信息,请参阅您的特定服务器端适配器文档。
由于验证错误作为页面组件道具在客户端可用,因此您可以根据它们的存在有条件地显示它们。请记住,当使用我们的第一方服务器适配器(例如 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>
$page.props.errors
对象访问错误。虽然在 Inertia 中处理错误类似于全页面表单提交,但 Inertia 提供了更多好处。事实上,您甚至不需要手动重新填充旧的表单输入数据。
当出现验证错误时,用户通常会被重定向回他们之前所在的表单页面。默认情况下,Inertia 会自动保留 组件状态,用于 post
、put
、patch
和 delete
请求。因此,所有旧的表单输入数据都将保持与用户提交表单时完全相同。
因此,剩下的唯一工作就是使用 errors
道具显示任何验证错误。
对于包含多个表单的页面,如果两个表单共享相同的字段名称,则在显示验证错误时可能会遇到冲突。例如,想象一个“创建公司”表单和一个“创建用户”表单,它们都具有一个 name
字段。由于这两个表单都将显示 page.props.errors.name
验证错误,因此在任一表单中为 name
字段生成验证错误会导致错误出现在两个表单中。
为了解决此问题,您可以使用“错误包”。错误包将从服务器返回的验证错误作用域到特定于该表单的唯一键中。继续以上面的示例,您可能有一个 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
中。