Modelable
#[Modelable] 属性指定子组件中可被父组件通过 wire:model 绑定的属性。
基本用法
将 #[Modelable] 属性应用到子组件的属性上,使其可绑定:
php
<?php // resources/views/components/⚡todo-input.blade.php
use Livewire\Attributes\Modelable;
use Livewire\Component;
new class extends Component {
#[Modelable] // [tl! highlight]
public $value = '';
};
?>
<div>
<input type="text" wire:model="value">
</div>现在父组件可以像绑定任何其他输入元素一样绑定到该子组件:
php
<?php // resources/views/components/⚡todos.blade.php
use Livewire\Component;
new class extends Component {
public $todo = '';
public function addTodo()
{
// Use $this->todo here...
}
};
?>
<div>
<livewire:todo-input wire:model="todo" /> <!-- [tl! highlight] -->
<button wire:click="addTodo">Add Todo</button>
</div>用户在 todo-input 组件中输入时,父组件的 $todo 属性会自动更新。
工作原理
没有 #[Modelable] 时,你需要手动处理父子之间的双向通信:
php
// Without #[Modelable] - manual approach
<livewire:todo-input
:value="$todo"
@input="todo = $event.value"
/>#[Modelable] 属性通过允许直接在组件上使用 wire:model 简化了这一点。
构建可复用输入组件
#[Modelable] 非常适合创建用起来像原生 HTML 输入的自定义输入组件:
php
<?php // resources/views/components/⚡date-picker.blade.php
use Livewire\Attributes\Modelable;
use Livewire\Component;
new class extends Component {
#[Modelable]
public $date = '';
};
?>
<div>
<input
type="date"
wire:model="date"
class="border rounded px-3 py-2"
>
</div>blade
{{-- Usage in parent --}}
<livewire:date-picker wire:model="startDate" />
<livewire:date-picker wire:model="endDate" />WARNING
组件的根元素不能是带有 wire:model 的表单控件。请用 <div> 等包装元素包裹输入。Livewire 会在根元素上注入 wire:model 和 x-modelable 以连接父级绑定——同一元素上的第二个 wire:model 会造成冲突。
修饰符
父组件可以使用 wire:model 修饰符来控制时机和网络请求:
blade
{{-- Live updates on every keystroke --}}
<livewire:todo-input wire:model.live="todo" />
{{-- Debounce updates --}}
<livewire:todo-input wire:model.live.debounce.500ms="todo" />
{{-- Throttle updates --}}
<livewire:todo-input wire:model.live.throttle.500ms="todo" />INFO
组件上的基于事件的修饰符
.blur、.change 和 .enter 等基于事件的修饰符控制的是特定元素上的 DOM 事件,而非响应式组件绑定。要控制 modelable 组件的同步时机,请将这些修饰符放在子组件内的实际输入元素上:
blade
{{-- Parent --}}
<livewire:todo-input wire:model="todo" />
{{-- Child component --}}
<input wire:model.blur="value" />示例:自定义富文本编辑器
下面是一个更复杂的富文本编辑器组件示例:
php
<?php // resources/views/components/⚡rich-editor.blade.php
use Livewire\Attributes\Modelable;
use Livewire\Component;
new class extends Component {
#[Modelable]
public $content = '';
};
?>
<div>
<div
x-init="
// Initialize your rich text editor library here
editor.on('change', () => {
$wire.content = editor.getContent()
})
"
>
<!-- Rich text editor UI -->
</div>
</div>blade
{{-- Usage --}}
<livewire:rich-editor wire:model="postContent" />限制
WARNING
每个组件只能有一个 modelable 属性
目前 Livewire 每个组件仅支持一个 #[Modelable] 属性,因此只有第一个会被绑定。
何时使用
在以下情况使用 #[Modelable]:
- 创建可复用输入组件(日期选择器、颜色选择器、富文本编辑器)
- 构建需要与 `wire:model` 配合使用的表单组件
- 将第三方 JavaScript 库包装为 Livewire 组件
- 创建带有特殊验证或格式化的自定义输入
了解更多
有关父子通信和数据绑定的更多信息,请参阅 嵌套组件文档。