表单验证

未匹配的标注
本文档最新版为 2.x,旧版本可能放弃维护,推荐阅读最新版!

表单验证

Livewire 中的验证应该类似于 Laravel 中标准的表单验证。

这是一个正在验证的 Livewire 表单的简单示例。

use Livewire\Component;

class ContactForm extends Component
{
    public $name;
    public $email;

    public function submit()
    {
        $this->validate([
            'name' => 'required|min:6',
            'email' => 'required|email',
        ]);

        // Execution doesn't reach here if validation fails.

        Contact::create([
            'name' => $this->name,
            'email' => $this->email,
        ]);
    }

    public function render()
    {
        return view('livewire.contact-form');
    }
}
<form wire:submit.prevent="submit">
    <input type="text" wire:model="name">
    @error('name') <span class="error">{{ $message }}</span> @enderror

    <input type="text" wire:model="email">
    @error('email') <span class="error">{{ $message }}</span> @enderror

    <button type="submit">Save Contact</button>
</form>

如果验证失败,则抛出标准的 ValidationException 异常(并被 Livewire捕获),并且该异常的 $errors 对象在组件的视图内可用。 因此,您拥有的任何现有代码(可能包括Blade)都将在此处处理其余应用程序中的验证。

您还可以将自定义错误提示添加到错误包中。

$this->addError('key', 'message')

实时验证

有时,在用户键入表单字段时验证表单字段很有用。 Livewire 使用 $this-> validateOnly() 方法使实时验证变得简单。

为了在每次更新后验证输入字段,我们可以使用 Livewire 的更新钩子:

use Livewire\Component;

class ContactForm extends Component
{
    public $name;
    public $email;

    public function updated($field)
    {
        $this->validateOnly($field, [
            'name' => 'min:6',
            'email' => 'email',
        ]);
    }

    public function saveContact()
    {
        $validatedData = $this->validate([
            'name' => 'required|min:6',
            'email' => 'required|email',
        ]);

        Contact::create($validatedData);
    }

    public function render()
    {
        return view('livewire.contact-form');
    }
}
<form wire:submit.prevent="saveContact">
    <input type="text" wire:model="name">
    @error('name') <span class="error">{{ $message }}</span> @enderror

    <input type="text" wire:model="email">
    @error('email') <span class="error">{{ $message }}</span> @enderror

    <button type="submit">Save Contact</button>
</form>

让我们确切地分解一下此示例中执行了哪些操作:

  1. 用户输入“名称”字段
  2. 当用户输入他们的名字时,如果少于6个字符,则会显示一条验证消息
  3. 用户可以切换到输入电子邮件,并且该名称的验证消息仍然显示
  4. 当用户提交表单时,将进行最终的验证检查,并且数据将保留下来。

如果您想知道,“为什么我需要validateOnly?我不能只使用validate吗?”。 原因是因为,对任何字段的每次更新都会验证所有字段。 这可能是令人讨厌的用户体验。 想象一下,如果您在表单的第一个字段中键入一个字符,突然之间每个字段都有一条验证消息。 validateOnly 可以防止这种情况,并且仅验证当前正在更新的字段。

直接处理错误消息

validate() 和 validateOnly() 方法应该可以处理大多数情况,但是有时您可能希望直接控制 Livewire 的内部 ErrorBag。

Livewire 提供了一些方法供您直接操作 ErrorBag。

在 Livewire 组件类中的任何位置,都可以调用以下方法:

$this->addError('email', 'The email field is invalid.');
// Quickly add a validation message to the error bag.

$this->resetErrorBag();
$this->resetValidation();
// These two methods do the same thing. The clear the error bag.
// If you only want to clear errors for one key, you can use:
$this->resetValidation('email');
$this->resetErrorBag('email');

$errors = $this->getErrorBag();
// This will give you full access to the error bag,
// allowing you to do things like this:
$errors->add('some-key', 'Some message');

验证测试

Livewire 为验证方案提供了有用的测试实用程序。 让我们为原始的“联系表”组件编写一个简单的测试。

/** @test  */
public function name_and_email_fields_are_required_for_saving_a_contact()
{
    Livewire::test('contact-form')
        ->set('name', '')
        ->set('email', '')
        ->assertHasErrors(['name', 'email']);
}

这很有用,但是我们可以更进一步,并针对特定的验证规则进行实际测试:

/** @test  */
public function name_and_email_fields_are_required_for_saving_a_contact()
{
    Livewire::test('contact-form')
        ->set('name', '')
        ->set('email', '')
        ->assertHasErrors([
            'name' => 'required',
            'email' => 'required',
        ]);
}

Livewire还提供了相反的 assertHasErrors-> assertHasNoErrors()

/** @test  */
public function name_field_is_required_for_saving_a_contact()
{
    Livewire::test('contact-form')
        ->set('name', '')
        ->set('email', 'foo')
        ->assertHasErrors(['name' => 'required'])
        ->assertHasNoErrors(['email' => 'required']);
}

有关这两种方法支持的语法的更多示例,请查看“测试文档”。

自定义验证

如果您希望在Livewire中使用自己的验证系统,那不是问题。 Livewire 将捕获 ValidationException 并将错误传递给视图,就像使用 $this-> validate() 一样。

例如:

use Livewire\Component;
use Illuminate\Support\Facades\Validator;

class ContactForm extends Component
{
    public $email;

    public function saveContact()
    {
        $validatedData = Validator::make(
            ['email' => $this->email],
            ['email' => 'required|email'],
            ['required' => 'The :attribute field is required'],
        )->validate();

        Contact::create($validatedData);
    }

    public function render()
    {
        return view('livewire.contact-form');
    }
}
<div>
    Email: <input wire:model.lazy="email">

    @if($errors->has('email'))
        <span>{{ $errors->first('email') }}</span>
    @endif

    <button wire:click="saveContact">Save Contact</button>
</div>

您可能想知道是否可以使用Laravel的 FormRequest。 由于 Livewire 的性质,挂接到 http 请求没有任何意义。 目前,此功能尚不可行或不建议使用。

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~