提交Laravel Livewire表单导致另一展示组件消失问题
问题描述
我有一个带表单弹窗的添加组件,点击提交按钮后,用于展示数据的Display组件会从页面消失,即便触发dispatch('refreshList')事件也无法恢复显示。
Display组件是一个包含foreach循环的表格,它和添加组件在视图里只是上下排列的关系。控制台没有任何报错,所有请求都正常发送,但表格就是不见了。
添加组件的创建实体方法
public function storeWork() { $this->validate(); $this->time_from = new DateTime($this->date .' '.$this->day_start); list($hours, $minutes) = explode(':', $this->length); $this->time_to = (clone $this->time_from)->add(new DateInterval("PT{$hours}H{$minutes}M")); $work = $this->create(); $this->dispatch('refreshList'); session()->flash('success', 'Výkaz byl přidán.'); $this->addNext(); } public function render(){ $orders = Order::where('state', "nevyrizena")->get(); $employees = Employee::all(); return view('livewire.WorkAddComponent', [ 'orders' => $orders, 'employees' => $employees, 'types' => $this->types, 'machines' => $this->machines, 'categories' => $this->categories, ]); }
添加组件的Blade视图
<div> <div x-data="{ expanded: false, form: true, closeform() { this.expanded = false; this.form = true }, openform() { this.expanded = true; this.form = true } }"> <button class="btn" type="button" x-data x-on:click="openform()"> ... </button> <div style="display: none;" x-show="expanded"> <div class="fixed left-0 top-0 z-40 h-screen w-screen bg-gray-800/90"></div> <div class="fixed top-10 z-50 max-h-full w-full items-center justify-center" aria-hidden="true" tabindex="-1"> <div class="relative w-6/12 rounded-lg bg-gray-700 p-10 text-white shadow"> ... <form wire:submit="storeWork"> @csrf <div x-show="form"> <div class="mb-4"> ... </div> <div class="mb-4"> ... </div> <div class="mb-4"> ... </div> <div class="form-footer flex gap-3">**!!!这个按钮不会出问题!!!!** <button class="btn" type="button" x-data x-on:click="form = false">继续</button> </div> </div> <div x-show="!form"> <div class="mb-4"> .... </div> <div class="mb-4"> ... </div> <div class="mb-4"> ... </div> <div class="mb-4"> ... </div> <div class="mb-4"> ... </div> <div class="mb-4"> ... </div> <div class="form-footer flex gap-3"> **!!!这两个按钮都会导致问题** <button class="btn-second-opt" type="submit" x-data x-on:click= "closeform()">保存并关闭</button> <button class="btn" type="submit">保存并添加下一个</button> </div> </div> </form> </div> @if (session('success')) ... @endif </div> </div> </div>
Display组件
#[On('refreshList')] public function refresh(){} public function render() { $work = Work::where('date', $this->displayDate)->paginate(10); $people = Employee::all(); return view('livewire.WorkDisplayComponent', [ 'work' => $work, 'people' => $people, ]); }
解决方案
1. 修复Alpine与Livewire的DOM冲突问题
提交按钮同时触发Alpine的closeform()和Livewire的表单提交,两者DOM操作互相干扰,导致Display组件DOM被意外移除。解决方式:
- 在
storeWork方法末尾添加Livewire事件,用来通知Alpine关闭弹窗:$this->dispatch('close-modal'); - 在Blade视图的x-data容器上监听该事件:
<div x-data="{...}" x-on:close-modal.window="closeform()"> - 移除提交按钮上的
x-on:click="closeform()",修改为:<button class="btn-second-opt" type="submit">保存并关闭</button>
2. 验证Display组件的日期状态
检查displayDate是否在刷新时被意外重置,导致查询无数据返回:
#[On('refreshList')] public function refresh() { // 确保displayDate为有效日期,比如默认当前日期 if(empty($this->displayDate)) { $this->displayDate = now()->format('Y-m-d'); } }
3. 移除多余的CSRF标签
Livewire表单会自动处理CSRF防护,手动添加的@csrf可能引发异常,直接删除表单中的@csrf即可。
内容的提问来源于stack exchange,提问作者Leoš Nevoral
相关产品推荐
相关产品推荐

