Skip to content
全部文档

加载状态

用户与 Livewire 组件交互时,在网络请求期间提供视觉反馈对体验很重要。Livewire 会自动给触发网络请求的元素加上 data-loading 属性,方便你样式化加载状态。

TIP

优先用 data-loading,而不是 wire:loading

Livewire 也提供 wire:loading 指令,用于在请求期间切换元素显示。wire:loading 对简单的显示/隐藏更省事,但限制更多(需要 wire:target 才能精确指定、跨组件事件场景不好用等)。多数情况下,应优先使用本指南所示的 data-loading 选择器。

基本用法

Livewire 会自动给触发网络请求的元素加上 data-loading 属性。这样你可以直接用 CSS 或 Tailwind 样式化加载状态,不必使用 wire:loading 指令。

下面是一个带 wire:click 的按钮简单示例:

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

点击按钮且请求进行中时,由于元素上存在 data-loading 属性,按钮会自动变为半透明。

工作原理

data-loading 属性会自动加到触发网络请求的元素上,包括:

  • 动作:wire:click="save"
  • 表单提交:wire:submit="create"
  • 属性更新:wire:model.live="search"
  • 事件:wire:click="$dispatch('refresh')"

重要的是,即使派发的事件由其他组件处理,该属性也会加上:

blade
<button wire:click="$dispatch('refresh-stats')">
    Refresh
</button>

即便事件由另一个组件接收,派发事件的按钮在网络请求期间仍会带上 data-loading 属性。

用 Tailwind 样式化

Tailwind v4 及以上为 data-loading 属性提供了强大的选择器。

基本样式

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

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

加载时显示元素

若只在加载中显示某个元素,使用 not-data-loading:hidden 变体:

blade
<button wire:click="save">
    Save
</button>

<span class="not-data-loading:hidden">
    Saving...
</span>

这种方式优于 hidden data-loading:block,因为它不依赖元素的 display 类型(flex、inline、grid 等)。

样式化子元素

父元素带有 data-loading 时,可用 in-data-loading: 变体样式化子元素:

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

WARNING

in-data-loading 变体会匹配所有祖先

只要任意祖先元素(无论多远)带有 data-loadingin-data-loading: 就会生效。若存在嵌套加载状态,可能出现意外行为。

样式化父元素

当父元素包含带 data-loading 的子元素时,用 has-data-loading: 变体样式化父元素:

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

点击按钮后,整个父级 div 会变为半透明。

样式化兄弟元素

可以用 Tailwind 的 peer 工具配合 peer-data-loading: 变体样式化兄弟元素:

blade
<div>
    <button wire:click="save" class="peer">
        Save
    </button>

    <span class="peer-data-loading:opacity-50">
        Saving...
    </span>
</div>

复杂选择器

对于更高级的样式需求,可以用任意变体定位特定元素:

blade
<!-- Style all direct children when loading -->
<div class="[&[data-loading]>*]:opacity-50" wire:click="save">
    <span>Child 1</span>
    <span>Child 2</span>
</div>

<!-- Style specific descendant elements -->
<button class="[&[data-loading]_.icon]:animate-spin" wire:click="save">
    <svg class="icon"><!-- spinner --></svg>
    Save
</button>

关于 Tailwind 的状态变体与任意选择器,详见 Tailwind CSS 文档

相对 wire:loading 的优势

相对传统的 wire:loading 指令,data-loading 属性方式有几项优势:

  1. 无需指定目标wire:loading 常常要用 wire:target 指定响应哪个动作;而 data-loading 会自动限定在触发请求的那个元素上。

  2. 样式更优雅:Tailwind 的变体系统能在标记里更干净、声明式地写加载样式。

  3. 支持事件:即使派发的事件由其他组件处理,也会加上该属性——这在以前用 wire:loading 很难做到。

  4. 更好组合:用 Tailwind 变体写样式,更容易与其他工具类和状态组合。

Tailwind 4 要求

INFO

高级变体需要 Tailwind v4+

in-data-loading:has-data-loading:peer-data-loading:not-data-loading: 变体需要 Tailwind CSS v4 或更高版本。若使用更早的 Tailwind,仍可用 data-loading: 语法或标准 CSS 定位该属性。

配合纯 CSS 使用

若不用 Tailwind,可以用标准 CSS 定位 data-loading 属性:

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

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

也可以用 CSS 样式化子元素:

css
[data-loading] .loading-text {
    display: inline;
}

[data-loading] .default-text {
    display: none;
}

另请参阅

  • wire:loading — 在请求期间显示和隐藏元素
  • 动作 — 在动作处理期间展示反馈
  • 表单 — 指示表单提交进度
  • 懒加载 — 为懒加载组件显示加载状态