表单验证
表单验证
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>
让我们确切地分解一下此示例中执行了哪些操作:
- 用户输入“名称”字段
- 当用户输入他们的名字时,如果少于6个字符,则会显示一条验证消息
- 用户可以切换到输入电子邮件,并且该名称的验证消息仍然显示
- 当用户提交表单时,将进行最终的验证检查,并且数据将保留下来。
如果您想知道,“为什么我需要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 请求没有任何意义。 目前,此功能尚不可行或不建议使用。