Skip to content

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()
    {
        // 在这里使用 $this->todo...
    }
};
?>

<div>
    <livewire:todo-input wire:model="todo" /> <!-- [tl! highlight] -->

    <button wire:click="addTodo">添加待办</button>
</div>

当用户在 todo-input 组件中输入时,父组件的 $todo 属性会自动更新。

工作原理

如果没有 #[Modelable],您需要手动处理父子组件之间的双向通信:

php
// 没有 #[Modelable] - 手动方法
<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
{{-- 在父组件中使用 --}}
<livewire:date-picker wire:model="startDate" />
<livewire:date-picker wire:model="endDate" />

修饰符

父组件可以使用 wire:model 修饰符,它们将按预期工作:

blade
{{-- 每次按键时实时更新 --}}
<livewire:todo-input wire:model.live="todo" />

{{-- 失焦时更新 --}}
<livewire:todo-input wire:model.blur="todo" />

{{-- 防抖更新 --}}
<livewire:todo-input wire:model.live.debounce.500ms="todo" />

示例:自定义富文本编辑器

以下是富文本编辑器组件的更复杂示例:

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-data="{
            content: $wire.entangle('content')
        }"
        x-init="
            // 在这里初始化您的富文本编辑器库
            editor.on('change', () => content = editor.getContent())
        "
    >
        <!-- 富文本编辑器 UI -->
    </div>
</div>
blade
{{-- 使用 --}}
<livewire:rich-editor wire:model="postContent" />

限制

每个组件只能有一个可模型化属性

目前 Livewire 每个组件只支持单个 #[Modelable] 属性,因此只会绑定第一个。

何时使用

在以下情况下使用 #[Modelable]

  • 创建可重用的输入组件(日期选择器、颜色选择器、富文本编辑器)
  • 构建需要与 wire:model 配合使用的表单组件
  • 将第三方 JavaScript 库包装为 Livewire 组件
  • 创建具有特殊验证或格式化的自定义输入

了解更多

有关父子组件通信和数据绑定的更多信息,请参阅嵌套组件文档