wire:loading

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

加载指示器是制作良好用户界面的重要组成部分。当向服务器发出请求时,它们向用户提供视觉反馈,以便他们知道正在等待某个进程完成。

基本用法

Livewire 提供了一个简单但极其强大的语法来控制加载指示器:wire:loading。将 wire:loading 添加到任何元素都将默认隐藏它(在 CSS 中使用 display: none),并在向服务器发送请求时显示它。

下面是一个 CreatePost 组件表单的基本示例,其中使用 wire:loading 切换加载消息

<form wire:submit="save">
<!-- ... -->
 
<button type="submit">Save</button>
 
<div wire:loading>
Saving post...
</div>
</form>

当用户按“保存”时,“正在保存帖子...”消息将出现在按钮下方,同时执行“保存”操作。当从服务器收到响应并由 Livewire 处理后,该消息将消失。

移除元素

或者,你可以附加 .remove 以获得相反的效果,默认显示元素并在向服务器发出请求期间隐藏它

<div wire:loading.remove>...</div>

切换类

除了切换整个元素的可见性之外,在向服务器发出请求期间通过打开和关闭 CSS 类来更改现有元素的样式通常很有用。此技术可用于更改背景颜色、降低不透明度、触发旋转动画等。

下面是一个使用 Tailwindopacity-50 的简单示例,在提交表单时使“保存”按钮变淡

<button wire:loading.class="opacity-50">Save</button>

与切换元素类似,你可以通过将 .remove 附加到 wire:loading 指令来执行反向类操作。在下面的示例中,当按下“保存”按钮时,按钮的 bg-blue-500 类将被移除

<button class="bg-blue-500" wire:loading.class.remove="bg-blue-500">
Save
</button>

切换属性

默认情况下,当提交表单时,Livewire 将自动禁用提交按钮,并在表单被处理时向每个输入元素添加 readonly 属性。

然而,除了这种默认行为之外,Livewire 还提供了 .attr 修饰符,允许你在元素上切换其他属性或切换表单外部元素上的属性

<button
type="button"
wire:click="remove"
wire:loading.attr="disabled"
>
Remove
</button>

由于上面的按钮不是提交按钮,因此在按下时不会被 Livewire 的默认表单处理行为禁用。相反,我们手动添加了 wire:loading.attr="disabled" 来实现此行为。

针对特定操作

默认情况下,每当组件向服务器发出请求时,都会触发 wire:loading

然而,在具有多个可以触发服务器请求的元素的组件中,你应该将加载指示器缩小到单个操作。

例如,考虑以下“保存帖子”表单。除了提交表单的“保存”按钮之外,还可能有一个“移除”按钮,对组件执行“移除”操作。

通过将 wire:target 添加到以下 wire:loading 元素,你可以指示 Livewire 仅在单击“移除”按钮时显示加载消息

<form wire:submit="save">
<!-- ... -->
 
<button type="submit">Save</button>
 
<button type="button" wire:click="remove">Remove</button>
 
<div wire:loading wire:target="remove">
Removing post...
</div>
</form>

当按下上面的“移除”按钮时,“正在移除帖子...”消息将显示给用户。但是,当按下“保存”按钮时,不会显示该消息。

针对多个操作

你可能会发现自己处于希望 wire:loading 对页面上的某些操作(但不是全部)做出反应的情况。在这些情况下,你可以将多个操作以逗号分隔传递到 wire:target。例如

<form wire:submit="save">
<input type="text" wire:model.blur="title">
 
<!-- ... -->
 
<button type="submit">Save</button>
 
<button type="button" wire:click="remove">Remove</button>
 
<div wire:loading wire:target="save, remove">
Updating post...
</div>
</form>

现在,只有在按下“移除”或“保存”按钮时才会显示加载指示器(“正在更新帖子...”),而不会在将 $title 字段发送到服务器时显示。

针对操作参数

在从页面上的多个地方使用不同参数触发相同操作的情况下,你可以通过传入其他参数将 wire:target 进一步限定到特定操作。例如,考虑以下场景,其中页面上每个帖子都有一个“移除”按钮

<div>
@foreach ($posts as $post)
<div wire:key="{{ $post->id }}">
<h2>{{ $post->title }}</h2>
 
<button wire:click="remove({{ $post->id }})">Remove</button>
 
<div wire:loading wire:target="remove({{ $post->id }})">
Removing post...
</div>
</div>
@endforeach
</div>

如果不将 {{ $post->id }} 传递给 wire:target="remove",则在单击页面上的任何按钮时都会显示“正在删除帖子...”消息。

但是,由于我们正在向 wire:target 的每个实例传递唯一参数,因此 Livewire 仅在将匹配参数传递给“remove”操作时才会显示加载消息。

不支持多个操作参数

目前,Livewire 仅支持通过单个方法/参数对来定位加载指示器。例如,支持 wire:target="remove(1)",但 wire:target="remove(1), add(1)" 不支持。

定位属性更新

Livewire 还允许你通过将属性名称传递给 wire:target 指令来定位特定的组件属性更新。

考虑以下示例,其中名为 username 的表单输入使用 wire:model.live 进行实时验证,因为用户正在输入

<form wire:submit="save">
<input type="text" wire:model.live="username">
@error('username') <span>{{ $message }}</span> @enderror
 
<div wire:loading wire:target="username">
Checking availability of username...
</div>
 
<!-- ... -->
</form>

当服务器使用新用户名更新时,当用户在输入字段中输入时,将显示“正在检查可用性...”消息。

排除特定加载目标

有时你可能希望为每个 Livewire 请求显示加载指示器,除了特定的属性或操作。在这些情况下,你可以像这样使用 wire:target.except 修饰符

<div wire:loading wire:target.except="download">...</div>

上面的加载指示器现在将显示在组件上的每个 Livewire 更新请求中,除了“download”操作。

自定义 CSS display 属性

当将 wire:loading 添加到元素时,Livewire 会更新元素的 CSS display 属性以显示和隐藏元素。默认情况下,Livewire 使用 none 来隐藏和 inline-block 来显示。

如果你正在切换使用 inline-block 以外的显示值的元素,例如以下示例中的 flex,则可以将 .flex 附加到 wire:loading

<div class="flex" wire:loading.flex>...</div>

以下是可用显示值的完整列表

<div wire:loading.inline-flex>...</div>
<div wire:loading.inline>...</div>
<div wire:loading.block>...</div>
<div wire:loading.table>...</div>
<div wire:loading.flex>...</div>
<div wire:loading.grid>...</div>

延迟加载指示器

在快速连接上,更新通常发生得如此之快,以至于加载指示器在被删除之前仅在屏幕上短暂闪烁。在这些情况下,指示器更像是一种干扰,而不是一种有用的帮助。

出于此原因,Livewire 提供了一个 .delay 修饰符来延迟指示器的显示。例如,如果你像这样向元素添加 wire:loading.delay

<div wire:loading.delay>...</div>

只有当请求花费超过 200 毫秒时,才会显示上述元素。如果在此之前请求完成,用户将永远看不到指示器。

要自定义延迟加载指示器的时间量,你可以使用 Livewire 的一个有用的间隔别名

<div wire:loading.delay.shortest>...</div> <!-- 50ms -->
<div wire:loading.delay.shorter>...</div> <!-- 100ms -->
<div wire:loading.delay.short>...</div> <!-- 150ms -->
<div wire:loading.delay>...</div> <!-- 200ms -->
<div wire:loading.delay.long>...</div> <!-- 300ms -->
<div wire:loading.delay.longer>...</div> <!-- 500ms -->
<div wire:loading.delay.longest>...</div> <!-- 1000ms -->