livewire表单验证关键在于验证时机、错误同步和服务端规则执行位置:需用wire:model.blur失焦校验,updated()中调用validateonly()触发服务端验证,@error('field')须匹配完整字段路径如'user.email'。

Livewire 表单验证不是“加个 @error 就完事”,关键在于**验证时机、错误同步、服务端规则执行位置**这三点没理清,很容易出现“前端提示了但后端没拦住”或“改了字段但错误不消失”的情况。
wire:model.live 和 wire:model.blur 的验证触发时机差异
两者都用于实时触发验证,但行为完全不同:
-
wire:model.live是“键入即发”,每按一次键就发一次请求校验——适合短字段(如邮箱前缀),但对长文本或含复杂规则的字段容易引发频繁请求和抖动 -
wire:model.blur是“失焦才校验”,用户离开输入框时才触发——更符合直觉,也避免无效中间状态干扰,推荐作为默认选择 - 注意:
wire:model(无修饰)只在组件提交或显式调用$this->validate()时校验,不会自动触发实时验证
服务端验证必须在 mount() 或 updated() 中显式调用
Livewire 不会自动为你运行 rules() 里的逻辑。即使你写了 public function rules(),它只是定义规则,不自动执行。
- 想让某个字段失焦就验证,得在
updated($propertyName)里判断并调用:$this->validateOnly($propertyName) - 例如:
public function updated($propertyName) { if (in_array($propertyName, ['email', 'password'])) { $this->validateOnly($propertyName); } } - 如果验证失败,
$this->validateOnly()会自动填充$errors并刷新视图;但要注意它不会中断后续逻辑,所以别把它放在可能修改状态的代码之后
@error('field') 显示错误的前提是服务端已触发过验证
Blade 中的 @error('email') 只读取 session 或当前请求中已存在的错误数据,它本身不触发任何验证。
- 如果你只写了
<input wire:model.blur="email">却没在updated或submit里调用validateOnly或validate,那么即使规则里写了'email' => 'required|email',@error也永远不显示 - 常见误操作:把
validate()放在submit()方法末尾——这时错误已经产生,但页面还没来得及渲染,用户看到的是空错误区;应提前验证,失败直接 return - 调试技巧:打开 Laravel Debugbar 的 Livewire 面板,看每次交互后 “Validation Errors” 是否有内容,没有就说明服务端根本没跑验证
最容易被忽略的一点:Livewire 的验证错误是**按字段名绑定的,而不是按表单名或模型属性路径**。比如你用 wire:model="user.email",那 @error('user.email') 才能匹配上,写成 @error('email') 就失效——这个点在嵌套属性或数组字段里特别容易踩坑。











