wire:model

您是视觉学习者吗?
通过我们深入的屏幕录制掌握 Livewire
立即观看

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

以下是使用 wire:model$title$content 属性与“创建帖子”组件中的表单输入绑定的一个简单示例

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
]);
 
// ...
}
}
<form wire:submit="save">
<label>
<span>Title</span>
 
<input type="text" wire:model="title">
</label>
 
<label>
<span>Content</span>
 
<textarea wire:model="content"></textarea>
</label>
 
<button type="submit">Save</button>
</form>

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

“为什么我的组件在输入时不会实时更新?”

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

自定义更新时间

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

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

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

实时更新

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

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

自定义防抖

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

可以通过在输入中追加 .debounce.Xms 来自定义此时间。以下是将去抖动更改为 250 毫秒的示例

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

在“blur”事件中更新

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

添加 .blur 有助于在希望更频繁地更新服务器但不是在用户输入时的情况。例如,实时验证是 .blur 有用的常见实例。

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

在“change”事件中更新

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

例如,如果你想在每次选择输入发生更改时运行验证,通过添加 .change,Livewire 会在用户选择新选项后立即发送网络请求并验证属性。与 .blur 相反,后者仅在用户从选择输入中切换标签后才更新服务器。

<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”的属性绑定到文本输入的方法

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

文本域输入

文本域元素类似地非常简单。只需将 wire:model 添加到文本域,该值就会被绑定

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

如果“content”值使用字符串初始化,Livewire 将使用该值填充文本域 - 无需执行类似以下操作

<!-- Warning: This snippet demonstrates what NOT to do... -->
 
<textarea type="text" wire:model="content">{{ $content }}</textarea>

复选框

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

单个复选框

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

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

现在,当 $receiveUpdates 值为 false 时,复选框将处于未选中状态。当然,当该值为 true 时,复选框将处于选中状态。

多个复选框

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

public $updateTypes = [];

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

<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"]

单选按钮

要针对单个属性在两个不同的值之间进行切换,可以使用单选按钮

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

选择下拉菜单

Livewire 简化了使用 <select> 下拉菜单的工作。在下拉菜单中添加 wire:model 时,当前选定的值将绑定到提供的属性名称,反之亦然。

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

以下是填充有静态州列表的选择下拉菜单示例

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

例如,当选择特定州(例如“阿拉斯加”)时,组件上的 $state 属性将设置为 AK。如果您希望将值设置为“阿拉斯加”而不是“AK”,则可以完全从 <option> 元素中省略 value="" 属性。

通常,您可以使用 Blade 动态构建下拉菜单选项

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

如果您没有默认选择特定选项,则可能希望默认显示静音占位符选项,例如“选择州”

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

正如您所见,选择菜单没有像文本输入那样的“占位符”属性。相反,您必须将 disabled 选项元素添加为列表中的第一个选项。

从属选择下拉菜单

有时您可能希望一个选择菜单从属于另一个选择菜单。例如,根据所选州而更改的城市列表。

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

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

<!-- States select menu... -->
<select wire:model.live="selectedState">
@foreach (State::all() as $state)
<option value="{{ $state->id }}">{{ $state->label }}</option>
@endforeach
</select>
 
<!-- Cities dependent select menu... -->
<select wire:model.live="selectedCity" wire:key="{{ $selectedState }}">
@foreach (City::whereStateId($selectedState->id)->get() as $city)
<option value="{{ $city->id }}">{{ $city->label }}</option>
@endforeach
</select>

同样,这里唯一的非标准内容是已添加到第二个选择中的 wire:key。这可确保在州更改时正确重置“selectedCity”值。

多选下拉菜单

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

<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 表单文档页面