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
相关产品推荐
相关产品推荐

