验证 Validation
它是如何工作的
Inertia 处理服务器端验证错误的工作方式与传统 ajax 驱动的表单略有不同,您可以从 422
响应中捕获验证错误并手动更新表单的错误状态。 这时因为 Inertia 永远不会接收 422
的响应。相反,Inertia 更像是标准的整页表单提交。以下是它如何做到的:
首先,您使用 Inertia 提交表单。在这期间如果出现服务器端验证错误, 您不会将这些错误作为 422
JSON 响应返回。相反,您需要(服务器端)重定向回您所在的表单页面,并在会话中刷新验证错误。一些诸如 Laravel 的框架会执行此操作。
接下来,只要会话中出现这些验证错误,它们就会自动与 Inertia 共享,使它们可用作客户端的页面道具,您可以在表单中显示这些道具。由于道具是响应性的,因此它们在表单完成时自动显示。
最后,由于 Inertia 应用程序从不会生成 422
响应,因此 Inertia 需要另一种方法来确定是否包含验证错误。要做到这一点,Inertia 会检查 page.props.errors
对象是否存在任何错误。如果出现错误,则会调用 onError()
回调,而不是 onSuccess()
回调。
共享错误
为了让您的服务器端验证错误能在客户端可用,您的服务器端框架必须通过 errors
道具进行共享。有些适配器(如 Laravel 适配器),会自动执行此操作。对于其它适配器,您可能需要手动去完成此操作。更多信息请参考您的具体服务器端适配器文档。
Laravel
class UsersController extends Controller
{
public function create()
{
return Inertia::render('Users/Create');
}
public function store()
{
Request::validate([
'first_name' => ['required', 'max:50'],
'last_name' => ['required', 'max:50'],
'email' => ['required', 'max:50', 'email'],
]);
$user = User::create(
Request::only('first_name', 'last_name', 'email')
);
return Redirect::route('users.show', $user);
}
}
显示错误
由于验证错误在客户端作为页面组件道具可用,因此您可以根据它们存在的情况有条件地展示。下面是一个例子。
Vue 2 / Vue 3
<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>
<script>
export default {
props: {
errors: Object,
},
data() {
return {
form: {
first_name: null,
last_name: null,
email: null,
},
}
},
methods: {
submit() {
this.$inertia.post('/users', this.form)
},
},
}
</script>
注意,在 Vue 适配器中,您也可以通过 $page.props.errors
对象访问错误。
重新填充输入
虽然在 Inertia 中处理错误类似于全页面表单提交,但这种方法实际上要好的多,因为您不需要手动重新填充旧的表单输入数据。
当发生验证错误时,用户会被自动重定向回他们已经存在的表单页面。而且,默认情况,Inertia 会自动为 post
、put
、patch
和 delete
请求保留组件状态。这意味着,所有旧表单输入数据都保持原样。
唯一改变的是 errors
属性,它现在包含验证错误。
错误保
对于具有多个表单页面,如果两个表单共享相同的字段名称,则在显示验证错误时可能会遇到冲突。例如,假设一个「创建公司」表单和一个「创建用户」表单都有一个 name
字段。由于两个表单都将显示 page.props.errors.name
验证错误,因此为任一表单中的 name
字段生成验证错误都会导致错误出现在两个表单中。
为了解决这个问题,您可以使用错误包。错误包将服务器返回的验证错误限定在特定于该表单的唯一键中。继续上面的示例,第一个表单可能有一个 createCompany
错误包,第二个表单有一个 createUser
错误包。
Inertia.post('/companies', data, {
errorBag: 'createCompany',
})
Inertia.post('/users', data, {
errorBag: 'createUser',
})
这样做会导致验证错误以 page.props.errors.createCompany
和 page.props.errors.createUser
的形式从服务器返回。
请注意,如果您使用 form helper,则无需使用错误包,因为验证错误会自动限定在形成对象。
本译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。
推荐文章: