返回

如何解决在 Laravel 中使用 Vee 验证 2.x 识别嵌套 vid 时出现的验证问题?

vue.js

在 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 属性可以防止验证器将嵌套字段分组到单独的包中,从而允许它们正确映射到顶层字段。

问:如果更改验证规则会导致其他验证错误怎么办?
答: 仔细检查更新后的验证规则,确保它们与表单中的字段相匹配。必要时,修改表单以匹配更新后的规则。

问:有没有其他方法可以解决这个问题?
答: 使用自定义中间件或创建一个自定义验证器可以提供替代解决方案。但是,建议使用概述的解决方案,因为它简单且有效。