使用Livewire与Alpine JS实现列表token删除动画的异常问题排查
问题原因
你在Blade中遍历$selected渲染token列表时,没有为每个循环项指定唯一的wire:key属性。
Livewire更新DOM时依赖diff算法识别节点,无唯一标识时会直接复用就近的同结构节点。当你删除某个token后,排在它之后的节点会被复用为新的同位置节点,被删除节点的Alpine状态show: false会被继承到复用节点上,最终导致后续token异常隐藏。
你后续添加的setTimeout(() => {show=true}, 300)属于补丁式修复,没有解决根因,反而会引发删除最后一个节点时出现多余动画的问题。
可行修复方案
- 为循环的token根元素添加唯一
wire:key属性,值直接使用唯一的用户ID即可,确保Livewire可以正确识别每个节点,不会出现错误复用:
@foreach ($selected as $item) <!-- 新增wire:key属性 --> <div wire:key="token-{{ $item->id }}" class="inline-block px-2 py-4" x-data="{show : false}" x-show="show" x-init="show = true" x-transition.duration.450> <span class="px-4 py-3 space-x-1 rounded-full shadow bg-indigo-300 text-white font-light"> <span>{{ $item->name }}</span> <span class="font-bold text-xl cursor-pointer" @click="show = false; setTimeout(() => {$wire.updateSelection({{ $item->id }})}, 450);"> × </span> </span> <input type="text" name="clients[]" type="number" value="{{ $item->id }}" hidden /> </div> @endforeach
- 移除你之前添加的多余的
setTimeout(() => {show=true}, 300)逻辑,同时可以把x-init里的450ms延迟去掉,直接设置show = true即可,新节点不会复用旧状态,添加时会直接触发进入动画,体验更流畅。 - 可选优化:把删除的setTimeout时长和x-transition的duration对齐为450ms,避免动画没跑完就触发DOM更新,出现跳变问题。
内容的提问来源于stack exchange,提问作者k-code
相关产品推荐
相关产品推荐

