Skip to content

wire:model

Livewire 使用 wire:model 可以轻松地将组件属性的值与表单输入绑定。

以下是在"创建文章"组件中使用 wire:model$title$content 属性与表单输入绑定的简单示例:

php
use Livewire\Component;
use App\Models\Post;

class CreatePost extends Component
{
    public $title = '';

    public $content = '';

    public function save()
    {
		$post = Post::create([
			'title' => $this->title
			'content' => $this->content
		]);

        // ...
    }
}
blade
<form wire:submit="save">
    <label>
        <span>Title</span>

        <input type="text" wire:model="title"> <!-- [tl! highlight] -->
    </label>

    <label>
        <span>Content</span>

        <textarea wire:model="content"></textarea> <!-- [tl! highlight] -->
    </label>

	<button type="submit">Save</button>
</form>

由于两个输入都使用 wire:model,当按下"保存"按钮时,它们的值将与服务器的属性同步。

"为什么我的组件在我键入时没有实时更新?"

如果你在浏览器中尝试过这个并且对标题为什么不会自动更新感到困惑,那是因为 Livewire 仅在提交“操作”时更新组件——比如按下提交按钮——而不是在用户在字段中键入时。这减少了网络请求并提高了性能。要在用户键入时启用“实时”更新,你可以使用 wire:model.live了解有关数据绑定的更多信息

自定义更新时机

默认情况下,Livewire 仅在执行操作时(如 wire:clickwire:submit)发送网络请求,而不是在更新 wire:model 输入时。

这通过减少网络请求大大提高了 Livewire 的性能,并为用户提供了更流畅的体验。

但是,在某些情况下,你可能希望更频繁地更新服务器,例如实时验证。

实时更新

要在用户在输入字段中键入时将属性更新发送到服务器,你可以将 .live 修饰符附加到 wire:model

html
<input type="text" wire:model.live="title">

自定义防抖

默认情况下,使用 wire:model.live 时,Livewire 会为服务器更新添加 150 毫秒的防抖。这意味着如果用户持续键入,Livewire 将等到用户停止键入 150 毫秒后再发送请求。

你可以通过将 .debounce.Xms 附加到输入来自定义此时间。以下是将防抖更改为 250 毫秒的示例:

html
<input type="text" wire:model.live.debounce.250ms="title">

在 "blur" 事件上更新

通过附加 .blur 修饰符,Livewire 仅在用户单击离开输入或按 Tab 键移动到下一个输入时发送带有属性更新的网络请求。

添加 .blur 对于你希望更频繁地更新服务器但不是在用户键入时的场景很有帮助。例如,实时验证是 .blur 有用的常见实例。

html
<input type="text" wire:model.blur="title">

在 "change" 事件上更新

有时 .blur 的行为并不完全是你想要的,而 .change 才是。

例如,如果你想在每次更改 select 输入时运行验证,通过添加 .change,Livewire 将在用户选择新选项后立即发送网络请求并验证属性。与 .blur 不同,.blur 仅在用户从 select 输入切换离开后才更新服务器。

html
<select wire:model.change="title">
    <!-- ... -->
</select>

对文本输入所做的任何更改都将自动与 Livewire 组件中的 $title 属性同步。

所有可用修饰符

修饰符描述
.live在用户键入时发送更新
.blur仅在 blur 事件上发送更新
.change仅在 change 事件上发送更新
.lazy.change 的别名
.debounce.[?]ms按指定的毫秒延迟对更新的发送进行防抖
.throttle.[?]ms按指定的毫秒间隔对网络请求更新进行节流
.number在服务器上将输入的文本值转换为 int
.boolean在服务器上将输入的文本值转换为 bool
.fill在页面加载时使用 "value" HTML 属性提供的初始值

输入字段

Livewire 开箱即用地支持大多数原生输入元素。这意味着你应该能够将 wire:model 附加到浏览器中的任何输入元素,并轻松地将属性绑定到它们。

以下是不同可用输入类型的完整列表以及如何在 Livewire 上下文中使用它们。

文本输入

首先,文本输入是大多数表单的基石。以下是如何将名为"title"的属性绑定到它的方法:

blade
<input type="text" wire:model="title">

文本域输入

Textarea 元素同样简单。只需将 wire:model 添加到 textarea,值就会被绑定:

blade
<textarea type="text" wire:model="content"></textarea>

如果"content"值用字符串初始化,Livewire 将用该值填充 textarea - 无需执行以下操作:

blade
<!-- 警告:此代码段演示了不应该做什么... -->

<textarea type="text" wire:model="content">{{ $content }}</textarea>

复选框

复选框可用于单个值,例如在切换布尔属性时。或者,复选框可用于在一组相关值中切换单个值。我们将讨论这两种场景:

单个复选框

在注册表单的末尾,你可能有一个复选框,允许用户选择接收电子邮件更新。你可能将此属性称为 $receiveUpdates。你可以使用 wire:model 轻松地将此值绑定到复选框:

blade
<input type="checkbox" wire:model="receiveUpdates">

现在,当 $receiveUpdates 值为 false 时,复选框将未选中。当然,当值为 true 时,复选框将被选中。

多个复选框

现在,假设除了允许用户决定接收更新之外,你的类中还有一个名为 $updateTypes 的数组属性,允许用户从各种更新类型中进行选择:

php
public $updateTypes = [];

通过将多个复选框绑定到 $updateTypes 属性,用户可以选择多个更新类型,它们将被添加到 $updateTypes 数组属性中:

blade
<input type="checkbox" value="email" wire:model="updateTypes">
<input type="checkbox" value="sms" wire:model="updateTypes">
<input type="checkbox" value="notification" wire:model="updateTypes">

例如,如果用户选中前两个框但不选中第三个框,则 $updateTypes 的值将为:["email", "sms"]

单选按钮

要在单个属性的两个不同值之间切换,你可以使用单选按钮:

blade
<input type="radio" value="yes" wire:model="receiveUpdates">
<input type="radio" value="no" wire:model="receiveUpdates">

下拉选择

Livewire 使处理 <select> 下拉菜单变得简单。将 wire:model 添加到下拉菜单时,当前选定的值将绑定到提供的属性名称,反之亦然。

此外,无需手动将 selected 添加到将被选中的选项 - Livewire 会自动为你处理。

以下是填充了静态州列表的 select 下拉菜单的示例:

blade
<select wire:model="state">
    <option value="AL">Alabama</option>
    <option value="AK">Alaska</option>
    <option value="AZ">Arizona</option>
    ...
</select>

当选择特定的州时,例如"Alaska",组件上的 $state 属性将设置为 AK。如果你希望将值设置为"Alaska"而不是"AK",可以完全省略 <option> 元素的 value="" 属性。

通常,你可能使用 Blade 动态构建下拉选项:

blade
<select wire:model="state">
    @foreach (\App\Models\State::all() as $state)
        <option value="{{ $state->id }}">{{ $state->label }}</option>
    @endforeach
</select>

如果你没有默认选择特定选项,你可能希望默认显示一个静音的占位符选项,例如"选择一个州":

blade
<select wire:model="state">
    <option disabled value="">选择一个州...</option>

    @foreach (\App\Models\State::all() as $state)
        <option value="{{ $state->id }}">{{ $state->label }}</option>
    @endforeach
</select>

如你所见,select 菜单没有像文本输入那样的"placeholder"属性。相反,你必须将 disabled 选项元素添加为列表中的第一个选项。

依赖下拉选择

有时你可能希望一个选择菜单依赖于另一个。例如,根据选择的州而变化的城市列表。

在大多数情况下,这按你的预期工作,但有一个重要的注意事项:你必须向更改的 select 添加 wire:key,以便 Livewire 在选项更改时正确刷新其值。

以下是两个选择的示例,一个用于州,一个用于城市。当州选择更改时,城市选择中的选项将正确更改:

blade
<!-- 州选择菜单... -->
<select wire:model.live="selectedState">
    @foreach (State::all() as $state)
        <option value="{{ $state->id }}">{{ $state->label }}</option>
    @endforeach
</select>

<!-- 城市依赖选择菜单... -->
<select wire:model.live="selectedCity" wire:key="{{ $selectedState }}"> <!-- [tl! highlight] -->
    @foreach (City::whereStateId($selectedState->id)->get() as $city)
        <option value="{{ $city->id }}">{{ $city->label }}</option>
    @endforeach
</select>

同样,这里唯一非标准的是已添加到第二个 select 的 wire:key。这确保当州更改时,"selectedCity"值将被正确重置。

多选下拉菜单

如果你使用"multiple" select 菜单,Livewire 按预期工作。在此示例中,选择州时将它们添加到 $states 数组属性,如果取消选择则将它们删除:

blade
<select wire:model="states" multiple>
    <option value="AL">Alabama</option>
    <option value="AK">Alaska</option>
    <option value="AZ">Arizona</option>
    ...
</select>

深入了解

有关在 HTML 表单上下文中使用 wire:model 的更完整文档,请访问 Livewire 表单文档页面