Skip to content

wire:loading

加载指示器是构建良好用户界面的重要组成部分。它们在向服务器发送请求时向用户提供视觉反馈,让用户知道他们正在等待一个过程完成。

考虑使用 data-loading 选择器代替

虽然 wire:loading 非常适合简单的显示/隐藏场景,但 Livewire v4 引入了在触发网络请求的元素上自动添加 data-loading 属性的功能。这种方法通常更简单、更灵活——你可以直接使用 Tailwind 设置加载状态的样式,而无需 wire:target 指令,并且即使在向其他组件派发事件时也能无缝工作。了解更多关于 data-loading →

基本用法

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

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

blade
<form wire:submit="save">
    <!-- ... -->

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

    <div wire:loading> 
        Saving post...
    </div>
</form>

当用户按下"Save"时,"Saving post..." 消息将在执行"save"操作时显示在按钮下方。当从服务器接收到响应并被 Livewire 处理后,消息将消失。

移除元素

或者,你可以添加 .remove 来实现相反的效果,默认显示元素并在向服务器发送请求时隐藏它:

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

切换类

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

以下是一个使用 Tailwindopacity-50 的简单示例,在提交表单时使"Save"按钮变淡:

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

与切换元素类似,你可以通过在 wire:loading 指令后添加 .remove 来执行相反的类操作。在下面的示例中,当按下"Save"按钮时,按钮的 bg-blue-500 类将被移除:

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

切换属性

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

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

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

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

定向特定操作

默认情况下,只要组件向服务器发出请求,wire:loading 就会被触发。

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

例如,考虑以下"保存文章"表单。除了提交表单的"Save"按钮外,可能还有一个执行组件上"remove"操作的"Remove"按钮。

通过将 wire:target 添加到以下 wire:loading 元素,你可以指示 Livewire 只在点击"Remove"按钮时显示加载消息:

blade
<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>

当按下上面的"Remove"按钮时,"Removing post..." 消息将显示给用户。然而,当按下"Save"按钮时,消息不会显示。

定向多个操作

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

blade
<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>

现在加载指示器("Updating post...")只会在按下"Remove"或"Save"按钮时显示,而不会在 $title 字段发送到服务器时显示。

定向操作参数

在同一操作从页面上的多个位置以不同参数触发的情况下,你可以通过传入额外的参数来进一步将 wire:target 的范围缩小到特定操作。例如,考虑以下场景,页面上的每篇文章都有一个"Remove"按钮:

blade
<div v-pre>
    @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",当点击页面上的任何按钮时,"Removing post..." 消息都会显示。

然而,因为我们向每个 wire:target 实例传递了唯一的参数,Livewire 只会在匹配的参数传递给"remove"操作时显示加载消息。

定向属性更新

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

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

blade
<form wire:submit="save" v-pre>
    <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>

当用户在输入字段中输入时,"Checking availability..." 消息将在服务器更新新用户名时显示。

排除特定加载目标

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

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

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

自定义 CSS display 属性

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

如果你正在切换一个使用 inline-block 以外的 display 值的元素,比如以下示例中的 flex,你可以在 wire:loading 后添加 .flex

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

以下是可用 display 值的完整列表:

blade
<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

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

上面的元素只会在请求超过 200 毫秒时出现。如果请求在此之前完成,用户将永远不会看到指示器。

要自定义延迟加载指示器的时间量,你可以使用 Livewire 提供的便捷间隔别名之一:

blade
<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 -->

使用 data-loading 样式

Livewire 自动为任何触发网络请求的元素添加 data-loading 属性。这允许你直接使用 CSS 或 Tailwind 设置加载状态的样式,而无需使用 wire:loading 指令。

使用 Tailwind 的 data 属性变体

你可以使用 Tailwind 的 data-loading 变体在元素加载时应用样式:

blade
<button
    wire:click="save"
    class="data-loading:opacity-50 data-loading:pointer-events-none"
>
    Save Changes
</button>

当点击按钮并且请求正在进行中时,它将自动变为半透明且不可点击。

使用 CSS

如果你没有使用 Tailwind,你可以使用标准 CSS 定位 data-loading 属性:

css
[data-loading] {
    opacity: 0.5;
    pointer-events: none;
}

button[data-loading] {
    background-color: #ccc;
    cursor: wait;
}

样式化父元素和子元素

你可以使用 has-data-loading: 变体在子元素具有 data-loading 时设置父元素的样式:

blade
<div class="has-data-loading:opacity-50">
    <button wire:click="save">Save</button>
</div>

或者使用 in-data-loading: 变体从具有 data-loading 的父元素设置子元素的样式:

blade
<button wire:click="save">
    <span class="in-data-loading:hidden">Save</span>
    <span class="hidden in-data-loading:block">Saving...</span>
</button>

另请参阅

  • 加载状态 — 使用 data-loading 属性的现代方法
  • 操作 — 在操作处理期间显示反馈
  • 表单 — 显示表单提交进度

参考

blade
wire:loading
wire:target="action"
wire:target="property"
wire:target.except="action"

修饰符

修饰符描述
.remove默认显示元素,加载时隐藏
.class="class-name"加载时添加 CSS 类
.class.remove="class-name"加载时移除 CSS 类
.attr="attribute"加载时添加 HTML 属性
.delay延迟 200ms 显示指示器
.delay.shortest延迟 50ms
.delay.shorter延迟 100ms
.delay.short延迟 150ms
.delay.long延迟 300ms
.delay.longer延迟 500ms
.delay.longest延迟 1000ms
.inline-flex使用 inline-flex display 值
.inline使用 inline display 值
.block使用 block display 值
.table使用 table display 值
.flex使用 flex display 值
.grid使用 grid display 值