开发者问题收集

Laravel Livewire 从组件中的验证器获取错误消息

2021-01-17
14474

在我的 register 表单中,我有一个 username 输入字段,我只想使用以下规则对其进行验证:

'required|regex:/^[a-zA-Z]+$/u|min:5|max:15|unique:users'

我想获取验证错误并通过另一种方式将其发送到视图,而不是像 Laravel 实现那样在视图中使用 bags 消息。例如:

<input type="text" class="form-control"
       name="username"
       wire:model="username"
       value="{{old('username')}}">

组件:

public function updatedUsername($username)
    {
        //$validator = $this->validate(['username' => 'required|regex:/^[a-zA-Z]+$/u|min:5|max:15|unique:users']);

        $validator = $this->validateOnly($username,['username' => 'required|regex:/^[a-zA-Z]+$/u|min:5|max:15|unique:users']);

        if ($validator->fail()) {
            // ...
        } else {
            // ...
        }
    }

在此 Component 中,我如何获取验证错误?

2个回答

使用 validate() / validateOnly() 时,如果验证失败,将抛出异常。Laravel 将拦截此验证错误,并在 blade 模板中处理它,以实现 @error('fieldName') 等功能。

为了使用 Livewire 实时挂入验证,您需要捕获该异常。要使用 @error('fieldName') 进行实时验证,您还应该在完成后重新抛出异常。

public function updated($field)
{
    try {
        $this->validateOnly($field);
    } catch (\Illuminate\Validation\ValidationException $e) {
        // Do your thing and use $validator here
        $validator = $e->validator;

        // ...

        // Once you're done, re-throw the exception
        throw $e;
    }
}

您可能已经注意到,这里没有任何规则的定义。这是因为它们应该在您的类的受保护属性 $rules 中定义( 除非您有非常令人信服的理由将其排除在该组件的全局规则集之外 )。

class Foo extends Component
{
    protected $rules = [
        'username' => 'required|regex:/^[a-zA-Z]+$/u|min:5|max:15|unique:users'
    ];
    
    // ....
}

如果您需要在规则中引入其他属性或使用函数,则可以删除该属性并声明 rules() 方法 - 这没有很好的记录,因此可能有点晦涩难懂。

class Foo extends Component
{
    public function rules() 
    {
        return [
            'username' => 'required|regex:/^[a-zA-Z]+$/u|min:5|max:15|unique:users'
        ];
    }
}

旁注:您可能不想使用正则表达式,而是希望使用 alpha 规则。

Qirel
2021-01-18

不必 检查 if ($validator->fails()) livewire 会为您完成此操作

如果验证失败,则会抛出标准 ValidationException(并由 Livewire 捕获),并且标准 $errors 对象在组件的视图中可用。因此,您拥有的任何现有代码(可能是 Blade 包含)用于处理应用程序其余部分的验证也将在此处应用。

只需将其添加到您的 blade 文件中(最好在输入标签之后)

@error('username')
    <div class="error-label">
        {{ $message }}
    </div>
@enderror
Digvijay
2021-01-17