Skip to content

加载状态

当用户与你的 Livewire 组件交互时,在网络请求期间提供视觉反馈对于良好的用户体验至关重要。Livewire 会自动向任何触发网络请求的元素添加 data-loading 属性,使样式化加载状态变得容易。

优先使用 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">
    保存更改
</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')">
    刷新
</button>

即使事件由不同的组件接收,分发事件的按钮在网络请求期间仍会收到 data-loading 属性。

使用 Tailwind 样式化

Tailwind v4 及以上版本提供了强大的选择器来处理 data-loading 属性。

基本样式化

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

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

在加载期间显示元素

要仅在加载活动时显示元素,使用 not-data-loading:hidden 变体:

blade
<button wire:click="save">
    保存
</button>

<span class="not-data-loading:hidden">
    保存中...
</span>

这种方法优于 hidden data-loading:block,因为它无论元素的显示类型(flex、inline、grid 等)如何都有效。

样式化子元素

当父元素具有 data-loading 属性时,你可以使用 in-data-loading: 变体样式化子元素:

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

in-data-loading 变体适用于所有祖先

in-data-loading: 变体将在任何祖先元素(无论在树中多远)具有 data-loading 属性时触发。如果你有嵌套的加载状态,这可能导致意外行为。

样式化父元素

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

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

当按钮被点击时,整个父 div 将变为半透明。

样式化兄弟元素

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

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

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

复杂选择器

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

blade
<!-- 加载时样式化所有直接子元素 -->
<div class="[&[data-loading]>*]:opacity-50" wire:click="save">
    <span>子元素 1</span>
    <span>子元素 2</span>
</div>

<!-- 样式化特定后代元素 -->
<button class="[&[data-loading]_.icon]:animate-spin" wire:click="save">
    <svg class="icon"><!-- 旋转器 --></svg>
    保存
</button>

Tailwind CSS 文档 中了解更多关于 Tailwind 的状态变体和任意选择器的信息。

相对于 wire:loading 的优势

data-loading 属性方法比传统的 wire:loading 指令提供了几个优势:

  1. 无需定位:与通常需要 wire:target 来指定响应哪个操作的 wire:loading 不同,data-loading 属性自动作用于触发请求的元素。

  2. 更优雅的样式化:Tailwind 的变体系统提供了一种更干净、更声明式的方式直接在标记中样式化加载状态。

  3. 与事件一起工作:即使在分发由其他组件处理的事件时也会添加该属性,这是以前使用 wire:loading 难以实现的。

  4. 更好的组合:使用 Tailwind 变体的样式化与其他工具类和状态更好地组合。

Tailwind 4 要求

高级变体需要 Tailwind v4+

in-data-loading:has-data-loading:peer-data-loading:not-data-loading: 变体需要 Tailwind CSS v4 或以上版本。如果你使用的是较早版本的 Tailwind,你仍然可以使用 data-loading: 语法或标准 CSS 定位 data-loading 属性。

使用纯 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 — 在请求期间显示和隐藏元素
  • 操作 — 在操作处理期间显示反馈
  • 表单 — 指示表单提交进度
  • 懒加载 — 显示懒加载组件的加载状态