You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Alpine JS与Livewire分发浏览器事件时第二次传参ID不匹配如何解决

问题根因

该异常是Livewire循环渲染列表元素时未指定唯一标识,导致重渲染时DOM diff计算错位,绑定的事件参数与实际元素不匹配导致的。

修复方案

1. 给循环列表项添加唯一wire:key

这是最核心的修复步骤,修改Blade视图中循环渲染todo项的代码,给<li>元素添加唯一的wire:key属性:

@forelse ($todos as $todo)    
    <li class="list-group-item d-flex justify-content-between" wire:key="todo-{{ $todo->id }}">
        {{ $todo->title }}
        <div x-data>
            <button
                class="btn btn-success"
                @click.prevent="$dispatch('toast-confirmation', {
                    id: {{ $todo->id }},
                    action: 'complete',
                    message: 'Are you sure to complete this task ?'
                })">Complete</button>
            <button
                class="btn btn-danger"
                @click.prevent="$dispatch('alert-confirmation', {
                    id: {{ $todo->id }},
                    action: 'delete',
                    message: 'Are you sure to delete this task ?'
                })">Delete</button>
        </div>
    </li>
@empty
    No data.
@endforelse

2. 避免事件监听器重复注册

修改alerts组件代码,用Blade的@once指令包裹脚本内容,防止组件重渲染时重复注册全局事件监听器,引发逻辑异常:

<div>
    @push('alerts')
        @once
        <script>
            // Alert Confirmation
            window.addEventListener('alert-confirmation', event => {
                Swal.fire({
                    title: 'Are you sure to delete this id : ' + event.detail.id + '?',
                    text: "You won't be able to revert this!",
                    icon: 'warning',
                    showCancelButton: true,
                    confirmButtonColor: '#3085d6',
                    cancelButtonColor: '#d33',
                    confirmButtonText: 'Yes, delete it!'
                }).then((result) => {
                    if (result.isConfirmed) {
                        Livewire.emit(event.detail.action, event.detail.id)
                    }
                })
            })

            // Alert Info
            window.addEventListener('alert-info', event => {
                Swal.fire({
                    icon: event.detail.icon,
                    title: 'Oops...',
                    text: 'Something went wrong!'
                })
            })
        </script>
        @endonce
    @endpush
</div>

3. 补全任务完成的更新逻辑

原代码中complete方法的update()调用未指定更新字段,会导致逻辑报错,修改为对应业务字段即可:

public function complete(Todo $todo)
{
    // 替换为实际的任务完成状态字段和值
    $todo->update(['is_completed' => true]);

    $this->dispatchBrowserEvent('toast', [
        'type' => 'success',
        'message' => 'Task has been completed'
    ]);
}

修复说明

  • wire:key会让Livewire在重渲染时精准匹配每个列表项和对应的DOM元素,不会出现元素与绑定数据错位的问题,从根本上解决ID参数不匹配的异常。
  • @once指令保证全局事件监听器只会被注册一次,避免同一个事件触发多次回调。

内容的提问来源于stack exchange,提问作者owf

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 00:45:00