如何解决在 Laravel 中使用 Vee 验证 2.x 识别嵌套 vid 时出现的验证问题?
2024-03-20 16:22:16
在 Laravel 中识别带嵌套 vid 的 Vee 验证 2.x
简介
在使用 Vee 验证 2.x 和 Nuxt JS 2.x 的项目中,当将 vid
prop 映射为嵌套值(例如“account.first_name”)时,一些页面可能会丢失传递“account”部分。这可能会导致 Laravel 认为某些字段未设置,从而引发验证错误。
问题
当尝试将表单数据映射到 Laravel 模型时,使用嵌套 vid 的 Vee 验证会导致验证问题,因为 Laravel 无法识别嵌套字段。
解决方案
为了解决此问题,需要进行以下更改:
1. 映射嵌套字段
在 Laravel 控制器中,使用 collect()
函数将嵌套字段映射到顶层字段。这可以通过将嵌套值作为数组合并到请求参数中来实现。
2. 更改验证规则
在 Fortify 的 CreateNewUser
类中,将验证规则中的键更改为顶层字段。
3. 禁用 Bag 属性
在前端 ValidationProvider 组件中,禁用 bag
属性,因为嵌套字段映射已经应用。
实施步骤
Laravel 控制器
// 映射嵌套字段
$fields = collect(array_merge(collect($request->input('account', []))->toArray(), [
'origin_source' => UserOriginSource::INVITE->value,
'origin_campaign' => (string) Str::of('onboarding')->trim(),
'timezone' => in_array($request->input('timezone', 'UTC'), timezone_identifiers_list())
? $request->input('timezone', 'UTC')
: 'Europe/London'
]))->toArray();
// 映射到顶层字段
$mapped = collect($fields)->mapWithKeys(function ($field, $key) {
return [(string) Str::of(Str::of('account.')->append($key))->trim() => $field];
})->toArray();
Fortify CreateNewUser 类
// 更改验证规则
public function create(array $input, string $bag = ''): User
{
$rules = [
'first_name' => ['required', 'string', 'min:2', 'max:128'],
'last_name' => ['nullable', 'min:2', 'max:128'],
'timezone' => ['required', 'timezone'],
'email' => [
'required',
'string',
'email',
'max:255',
'indisposable',
Rule::unique(User::class),
],
'origin_source' => [
'required',
'string',
'in:'.implode(',', array_column(UserOriginSource::cases(), 'value')),
],
'origin_source_other' => ['required_if:origin_source,other', 'max:128'],
'origin_campaign' => [
'nullable',
'string',
],
'password' => $this->passwordRules(),
];
// 映射到顶层字段
Validator::make($input, collect($rules)->mapWithKeys(function ($rule, $key) use ($bag) {
if ($bag == '') return [$key => $rule];
return [(string) Str::of(Str::of($bag)->append('.')->append($key))->trim() => $rule];
})->toArray())->validate();
}
前端 ValidationProvider 组件
<!-- 禁用 Bag 属性 -->
<ValidationProvider
name="Company name"
vid="company.company_name"
rules="required|min:2"
v-slot="{ errors, classes }"
>
...
</ValidationProvider>
总结
通过遵循这些步骤,您将能够在使用 Vee 验证 2.x 的 Laravel 项目中正确识别带嵌套 vid 的验证。这将确保表单数据正确映射到模型,并防止因缺少字段而导致的验证错误。
常见问题解答
问:为什么映射嵌套字段是必要的?
答: 嵌套字段映射将嵌套值映射到顶层字段,以便 Laravel 可以识别它们进行验证。
问:为什么需要更改验证规则中的键?
答: 验证规则中的键必须与顶层字段匹配,以便验证器可以正确应用规则。
问:禁用 Bag 属性有什么作用?
答: 禁用 Bag 属性可以防止验证器将嵌套字段分组到单独的包中,从而允许它们正确映射到顶层字段。
问:如果更改验证规则会导致其他验证错误怎么办?
答: 仔细检查更新后的验证规则,确保它们与表单中的字段相匹配。必要时,修改表单以匹配更新后的规则。
问:有没有其他方法可以解决这个问题?
答: 使用自定义中间件或创建一个自定义验证器可以提供替代解决方案。但是,建议使用概述的解决方案,因为它简单且有效。