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

Livewire搜索功能异常:输入不同关键词始终返回相同结果

问题

在Laravel项目中使用Livewire实现商品搜索功能时遇到异常:搜索框输入不同关键词,始终返回相同的搜索结果,即便搜索文本已明确变更。

组件代码(ProductList.php)

<?php

namespace App\Livewire;

use App\Models\Cigarette;
use App\Models\Liquid;
use Livewire\Component;
use Gloudemans\Shoppingcart\Facades\Cart;

class ProductList extends Component
{
    public $search = '';

    public function render()
    {
        $searchTerm = trim($this->search);

        $filteredCigarettes = Cigarette::whereRaw('LOWER(name) like ?', ['%' . strtolower($searchTerm) . '%'])->get();
        $filteredLiquids = Liquid::whereRaw('LOWER(name) like ?', ['%' . strtolower($searchTerm) . '%'])->get();

        return view('livewire.product-list', [
            'cigarettes' => $filteredCigarettes,
            'liquids' => $filteredLiquids,
        ]);
    }
}

视图代码(livewire/product-list.blade.php)

<div class="grid">

    <input wire:model.live.debounce.1000ms="search" class="searchbar" type="text">

    {{-- Cigarettes --}}
    @forelse($cigarettes as $cigarette)
        <livewire:cigarette-card :cigarette="$cigarette"/>
    @empty
        <div class="#">
            No cigarettes in the database
        </div>
    @endforelse

    {{-- Liquids --}}
    @forelse($liquids as $liquid)
        <livewire:liquid-card :liquid="$liquid"/>
    @empty
        <div class="#">
            No liquids in the database
        </div>
    @endforelse
</div>

调试情况

添加调试代码后:

class ProductList extends Component
{
    public $search = '';

    public function render()
    {
        $searchTerm = trim($this->search);

        dump($this->search);

        dump(Cigarette::where('name', 'like', '%'.'Gene'.'%')->get());

        $filteredCigarettes = Cigarette::whereRaw('LOWER(name) like ?', ['%' . strtolower($searchTerm) . '%'])->get();
        $filteredLiquids = Liquid::whereRaw('LOWER(name) like ?', ['%' . strtolower($searchTerm) . '%'])->get();

        dump($filteredCigarettes);

        return view('livewire.product-list', [
            'cigarettes' => $filteredCigarettes,
            'liquids' => $filteredLiquids,
        ]);
    }
}

调试结果显示$search变量已正确接收输入值,但查询始终返回同一条“Pod Smok System”结果:

"gene" // app\Livewire\ProductList.php:20 

Illuminate\Database\Eloquent\Collection {#1345 ▼ // app\Livewire\ProductList.php:22
  #items: array:1 [▶]
  #escapeWhenCastingToString: false
}
Illuminate\Database\Eloquent\Collection {#581 ▼ // app\Livewire\ProductList.php:27
  #items: array:1 [▶]
  #escapeWhenCastingToString: false
}

已尝试用whereRaw('LOWER(name) like ?', ...)处理大小写问题,给输入框添加debounce.500ms减少请求频率,但问题仍未解决。

解决方案

1. 给循环子组件添加唯一wire:key属性

循环渲染<livewire:cigarette-card>和<livewire:liquid-card>时未指定唯一wire:key,Livewire无法正确识别DOM元素更新,导致复用旧组件实例,显示内容不刷新。

修改视图代码:

{{-- Cigarettes --}}
@forelse($cigarettes as $cigarette)
    <livewire:cigarette-card :cigarette="$cigarette" wire:key="cigarette-{{ $cigarette->id }}"/>
@empty
    <div class="#">
        数据库中没有香烟
    </div>
@endforelse

{{-- Liquids --}}
@forelse($liquids as $liquid)
    <livewire:liquid-card :liquid="$liquid" wire:key="liquid-{{ $liquid->id }}"/>
@empty
    <div class="#">
        数据库中没有烟油
    </div>
@endforelse

2. 验证数据库查询的准确性

虽然$search变量值正确,但需确认查询逻辑是否正常执行:

  • 临时将查询条件替换为静态值(比如搜索"test"),检查返回结果是否符合预期
  • 输出最终执行的SQL语句和绑定参数,验证参数是否正确传入:
    $query = Cigarette::whereRaw('LOWER(name) like ?', ['%' . strtolower($searchTerm) . '%']);
    dump($query->toSql()); // 查看生成的SQL语句
    dump($query->getBindings()); // 查看绑定的参数值
    

3. 清除Livewire缓存并检查前端状态

  • 运行php artisan livewire:clear清除Livewire缓存
  • 检查浏览器控制台是否存在JS错误,Livewire实时更新依赖前端JS,错误会导致更新中断
  • 确认组件查询未被意外缓存(比如误用cache()方法包裹查询)

4. 简化查询语法(可选优化)

可以用Laravel内置的查询方法替代whereRaw,写法更简洁且安全:

$filteredCigarettes = Cigarette::where('name', 'like', '%' . trim($this->search) . '%')
    ->orWhereRaw('LOWER(name) LIKE ?', ['%' . strtolower(trim($this->search)) . '%'])
    ->get();

内容的提问来源于stack exchange,提问作者d.shved

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 17:21:15