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

Livewire DOM Diffing问题:输入框失焦如何解决?

Livewire 标签输入框添加后失焦问题解决

问题场景

现有Livewire Blade模板代码如下:

<div class="box-wrapper">
    <ul>
        @foreach($tags as $tag)
            <li wire:key="tag-{{ $loop->index }}">
                {{ $tag }}
            </li>
        @endforeach

        <input
            type="text"
            wire:model.defer="tagInputValue"
            wire:key="tag-input"
            wire:keydown.enter="add()"
        />
    </ul>
</div>

按下Enter执行add()方法时,会将输入值追加到$tags数组并重置输入框值,但每次操作后输入框会失焦,影响体验。已尝试将<input>移到<ul>外或循环前,但均不符合布局/样式要求。

问题原因

核心问题出在<li>的wire:key使用了$loop->index:

  • 每次新增标签后,原有标签对应的$loop->index会递增,导致它们的wire:key值发生变化
  • Livewire的DOM diffing机制会将这些<li>判定为全新元素,重新渲染整个foreach生成的列表
  • 尽管<input>有独立的wire:key,但它紧跟在循环之后,当前面的列表被完全重新渲染时,Livewire会重新生成<ul>的所有子元素,包括该输入框,最终导致输入框失焦

解决方案

将<li>的wire:key改为基于标签内容的唯一标识(因add()方法会检查重复,标签内容本身唯一):

<div class="box-wrapper">
    <ul>
        @foreach($tags as $tag)
            <!-- 改用标签内容作为wire:key的唯一标识 -->
            <li wire:key="tag-{{ $tag }}">
                {{ $tag }}
            </li>
        @endforeach

        <input
            type="text"
            wire:model.defer="tagInputValue"
            wire:key="tag-input"
            wire:keydown.enter="add()"
        />
    </ul>
</div>

修改后:

  • 新增标签时,原有<li>的wire:key不会改变,Livewire只会在列表末尾新增一个<li>元素,不会重新渲染原有内容
  • <input>不会被重新创建,仅会被重置输入值,因此能保持焦点

如果存在标签内容重复的场景(即使add()做了校验,也可提前为每个标签分配唯一ID),可改用ID作为wire:key,比如:

<li wire:key="tag-{{ $tag->id }}">
    {{ $tag->name }}
</li>

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 22:00:24