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

Laravel Livewire中输入框值在其他输入操作后丢失问题求助

问题原因

你遇到的闪烁和值丢失问题,核心原因是直接用jQuery操作DOM修改输入框值,但没有同步更新Livewire组件的后端状态。Livewire是数据驱动框架,每次组件状态更新(比如其他输入框触发wire:model更新)时,会重新渲染DOM并根据组件内的$products数组值覆盖输入框内容,导致你手动修改的DOM值被重置。

解决方案

完全基于Livewire的状态管理实现条码搜索填充逻辑,避免jQuery和Livewire的DOM操作冲突:

1. 调整Livewire组件代码

在你的Livewire组件类中添加条码搜索方法,维护$products数组的状态:

<?php

namespace App\Http\Livewire;

use Livewire\Component;
use App\Models\Product; // 替换为你的商品模型

class ProductRepeater extends Component
{
    public $products = [];

    public function mount()
    {
        // 初始化一行空数据
        $this->products[] = [
            'product_id' => '',
            'product' => '',
            'barcode' => '',
            'tainia' => '',
            'lot' => '',
            'expdate' => '',
            'quantity' => 1
        ];
    }

    public function addProduct()
    {
        $this->products[] = [
            'product_id' => '',
            'product' => '',
            'barcode' => '',
            'tainia' => '',
            'lot' => '',
            'expdate' => '',
            'quantity' => 1
        ];
    }

    public function removeProduct($index)
    {
        unset($this->products[$index]);
        $this->products = array_values($this->products); // 重新索引数组
    }

    // 条码搜索并填充数据
    public function searchBarcode($index)
    {
        $barcode = $this->products[$index]['barcode'];
        if(strlen($barcode) != 13) return;

        $product = Product::where('barcode', $barcode)->first();
        if(!$product) return;

        // 更新组件内状态,Livewire会自动同步到DOM
        $this->products[$index]['product_id'] = $product->id;
        $this->products[$index]['product'] = $product->name;
    }

    public function render()
    {
        return view('livewire.product-repeater');
    }
}

2. 修改前端Blade代码

移除jQuery脚本,改用Livewire的wire:keyup事件触发搜索,同时给循环项添加唯一wire:key避免渲染异常:

<table>
    <tbody>
        @foreach ($products as $index => $product)
            <tr class="repeater-item" wire:key="product-{{ $index }}">
                <td>
                    <input class="prod-id" type="text" wire:model="products.{{ $index }}.product_id" readonly>
                </td>
                <td>
                    <input class="prod-name" type="text" wire:model="products.{{ $index }}.product" readonly>
                </td>
                <td>
                    <input class="search" type="text" wire:model="products.{{ $index }}.barcode" wire:keyup.debounce.500ms="searchBarcode({{ $index }})">
                </td>
                <td>
                    <input class="prod-tainia" type="text" wire:model="products.{{ $index }}.tainia">
                </td>
                <td>
                    <input class="prod-lot" type="text" wire:model="products.{{ $index }}.lot">
                </td>
                <td>
                    <input class="prod-expdate" type="text" wire:model="products.{{ $index }}.expdate">
                </td>
                <td>
                    <input type="number" wire:model="products.{{ $index }}.quantity">
                </td>
                <td>
                    <button type="button" wire:click="removeProduct({{ $index }})">Remove</button>
                </td>
            </tr>
        @endforeach
    </tbody>
</table>

<button type="button" wire:click="addProduct">Add Product</button>

关键优化点说明

  • 移除jQuery操作:所有数据更新都通过Livewire的wire:model和组件方法完成,确保组件状态和DOM完全同步,避免渲染冲突。
  • 添加wire:key:循环项必须设置唯一wire:key,帮助Livewire准确识别DOM元素,避免重新渲染时出现闪烁或错位。
  • 防抖处理:用wire:keyup.debounce.500ms延迟触发搜索,避免用户输入过程中频繁请求接口,提升性能。
  • 只读设置:自动填充的product_id和product输入框设置为readonly,防止用户手动修改导致状态不一致。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 05:47:46