如何在Livewire中创建支持wire:model并向父组件传值的输入组件?
在Livewire中实现支持数据绑定的输入组件
你的问题核心是:Livewire组件是独立的状态实例,直接在子组件用wire:model="value"无法自动同步父组件属性,需要通过事件触发或Livewire 3专属的Modelable特性实现双向绑定。
解决方案一:兼容Livewire 2/3的事件同步法
1. 子组件类(FormInput.php)
定义接收父组件值的属性,在值更新时向上触发事件通知父组件:
<?php namespace App\Livewire\Components\Form; use Livewire\Component; class FormInput extends Component { public $value; public $for; public $label; public $placeholder; // 监听value属性变化,触发父组件更新 public function updatedValue($newValue) { $this->emitUp('updateParentModel', $newValue); } public function render() { return view('livewire.components.form.form-input'); } }
2. 子组件模板
将wire:model="value"改为绑定:value="$value",监听输入事件同步组件内部值:
<div class="px-4"> @isset($label) <label for="{{ $for }}" class="block mb-2 text-sm font-medium text-gray-400 dark:text-gray-300">{{ $label }}</label> @endisset <input type="text" id="{{ $for }}" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" placeholder="{{ $placeholder ?? '' }}" required :value="$value" @input="$wire.set('value', $event.target.value)"> </div>
3. 父组件类(QuestionForm.php)
监听子组件事件,更新自身属性:
<?php namespace App\Livewire; use Livewire\Component; class QuestionForm extends Component { public $text; // 注册监听事件 protected $listeners = [ 'updateParentModel' => 'updateText' ]; // 更新父组件的text属性 public function updateText($newValue) { $this->text = $newValue; } public function save() { // 你的保存逻辑 } public function render() { return view('livewire.question-form'); } }
4. 父组件模板
给子组件传递:value="$text",替代原来的wire:model:
<div> <form wire:submit.prevent="save"> @csrf <livewire:components.form.form-input for="question" label="What is your question?" :value="$text" placeholder="Enter your question"> <x-slot:label> <em>What is your question?</em> </x-slot:label> </livewire:components.form.form-input> <div class="my-4"> <div class="text-3xl">Options</div> </div> <livewire:components.button type="submit" text="Submit"></livewire:components.button> </form> </div>
解决方案二:Livewire 3专属的Modelable特性
如果使用Livewire 3,可通过#[Modelable]标记属性,直接实现双向绑定,无需手动处理事件:
1. 子组件类
给$value属性添加#[Modelable]注解:
<?php namespace App\Livewire\Components\Form; use Livewire\Component; use Livewire\Attributes\Modelable; class FormInput extends Component { #[Modelable] // 标记该属性支持wire:model绑定 public $value; public $for; public $label; public $placeholder; public function render() { return view('livewire.components.form.form-input'); } }
2. 子组件模板
保留wire:model.lazy="value"即可:
<div class="px-4"> @isset($label) <label for="{{ $for }}" class="block mb-2 text-sm font-medium text-gray-400 dark:text-gray-300">{{ $label }}</label> @endisset <input type="text" id="{{ $for }}" class="bg-gray-50 border border-gray-300 text-gray-900 text-sm rounded-lg focus:ring-blue-500 focus:border-blue-500 block w-full p-2.5" placeholder="{{ $placeholder ?? '' }}" required wire:model.lazy="value"> </div>
3. 父组件模板
直接使用你原来的写法,wire:model.lazy="text"会自动同步:
<div> <form wire:submit.prevent="save"> @csrf <livewire:components.form.form-input for="question" label="What is your question?" wire:model.lazy="text"> <x-slot:label> <em>What is your question?</em> </x-slot:label> </livewire:components.form.form-input> <div class="my-4"> <div class="text-3xl">Options</div> </div> <livewire:components.button type="submit" text="Submit"></livewire:components.button> </form> </div>
内容的提问来源于stack exchange,提问作者Daniel Haven
相关产品推荐
相关产品推荐

