Livewire嵌套组件搭配AlpineJS @entangle指令状态同步异常求助
问题核心原因
- Livewire 父子组件默认属性传递是单向的:你从父组件传给子Fruit组件的
$fruit只是值拷贝,子组件修改自身的$fruit属性不会自动同步到父组件的$fruits数组。 - 嵌套数组属性绑定路径错误,之前出现的
[object Object]提示就是因为@entangle拿到了整个数组对象而不是对应的字符串属性值。 contenteditable元素用innerHTML取值会带多余HTML标签/空格,容易引发非预期的赋值问题。
解决方案
推荐用直接绑定父组件数组下标的方式实现,代码更简洁:
第一步:精简Fruit子组件代码
删除子组件中多余的$fruit属性,只保留数组下标参数即可:
<?php namespace App\Http\Livewire; use Livewire\Component; class Fruit extends Component { public string $fruitIndex; public function render() { return view('livewire.fruit'); } }
第二步:修复父组件子组件调用语法
调整list-fruit.blade.php循环部分,给wire:key加唯一前缀避免冲突:
<div class="w-full container mx-auto"> <h3 class="text-2xl font-sembibold"> Fruits </h3> <div id="fruits"> @foreach($fruits as $fruitIndex=> $fruit) <livewire:fruit :fruitIndex="$fruitIndex" :wire:key="'fruit-'.$fruitIndex" > @endforeach </div> </div>
第三步:修改子组件Blade模板绑定逻辑
直接通过下标绑定父组件的$fruits数组对应属性,同时修复contenteditable取值逻辑:
<div x-data="{ type: @entangle('fruits.'.$fruitIndex.'.type'), color: @entangle('fruits.'.$fruitIndex.'.color') }" x-init="console.log(type)"> <div> <!-- 用textContent.trim()避免多余空格和标签 --> <div @blur="type = $event.target.textContent.trim()" contenteditable="true" x-text="type"></div> <div @blur="color = $event.target.textContent.trim()" contenteditable="true" x-text="color"></div> </div> <div> $type @ Livewire: {{ $fruits[$fruitIndex]['type'] }} $color @ Livewire: {{ $fruits[$fruitIndex]['color'] }} </div> <div> type @ AlpineJS: <span x-text="type"></span> color @ AlpineJS: <span x-text="color"></span> </div> </div>
这里的@entangle直接指向父组件的数组属性路径,修改时会自动双向同步,不需要额外加事件监听逻辑。
内容的提问来源于stack exchange,提问作者Tanuki
相关产品推荐
相关产品推荐

