Livewire foreach遍历触发Trying to get property 'id' of non-object错误
问题根因
- 核心原因:你将Eloquent模型集合存储在公共属性
$listaTareas中,Livewire会自动序列化所有公共属性传递到前端,下次请求触发组件重渲染时,序列化的模型反序列化后会变成普通数组而非原模型对象,因此用->访问属性就会抛出「尝试获取非对象的id属性」错误。 - 辅助诱因:循环渲染列表时未添加
wire:key属性,Livewire做DOM差分更新时无法准确匹配列表节点,容易出现数据错位问题。 - 隐藏bug:删除按钮嵌套在带点击事件的div内部,点击按钮时会同时触发父div的
show事件和按钮的delete事件,导致重复请求;且delete方法未定义接收参数的形参,后续调用也会报错。
修复方案
第一步:调整Livewire组件代码
移除公共属性$listaTareas,改为每次渲染时直接查询最新数据,避免模型序列化异常,同时修复参数缺失问题:
<?php namespace App\Http\Livewire; use Livewire\Component; use App\Models\Tarea; class Index extends Component { public $tid; public $nombre; public $descripcion; public function create() { $tarea = new Tarea(); $tarea->nombre = $this->nombre; $tarea->descripcion = $this->descripcion; if ($tarea->save()) { $this->tid = 'ID: '.$tarea->id; // 可选:清空输入框 $this->nombre = ''; $this->descripcion = ''; } } public function show($id) { $this->descripcion = "Show $id"; // 实际业务可扩展为查询对应任务赋值到属性 // $tarea = Tarea::findOrFail($id); // $this->nombre = $tarea->nombre; // $this->tid = $tarea->id; } // 补充接收id的形参 public function delete($id) { // 实际业务可扩展为删除对应任务 // Tarea::destroy($id); $this->descripcion = "Delete $id"; } public function render() { // 每次渲染直接查询最新列表,无需存入公共属性 $listaTareas = Tarea::all(); return view('livewire.index', compact('listaTareas')); } }
第二步:调整视图循环代码
添加wire:key保证列表节点唯一标识,同时给删除按钮加.stop修饰符阻止事件冒泡:
@foreach($listaTareas as $t) {{-- 新增wire:key,值必须全局唯一 --}} <div class="data col-12" wire:click="show({{ $t->id }})" wire:key="tarea-{{ $t->id }}"> <label>{{ $t->nombre }}</label> <label class="hint">ID: {{ $t->id }}</label> {{-- 新增.stop修饰符,阻止点击事件冒泡到父div --}} <button type="button" class="btn btn-danger" wire:click.stop="delete({{ $t->id }})"> <i class="fas fa-trash"></i> </button> </div> @endforeach
内容的提问来源于stack exchange,提问作者Asu Suárez
相关产品推荐
相关产品推荐

