加载状态
用户与 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 的按钮简单示例:
<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')"
重要的是,即使派发的事件由其他组件处理,该属性也会加上:
<button wire:click="$dispatch('refresh-stats')">
Refresh
</button>即便事件由另一个组件接收,派发事件的按钮在网络请求期间仍会带上 data-loading 属性。
用 Tailwind 样式化
Tailwind v4 及以上为 data-loading 属性提供了强大的选择器。
基本样式
使用 Tailwind 的 data-loading: 变体,在元素加载时应用样式:
<button wire:click="save" class="data-loading:opacity-50">
Save
</button>加载时显示元素
若只在加载中显示某个元素,使用 not-data-loading:hidden 变体:
<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: 变体样式化子元素:
<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-loading,in-data-loading: 就会生效。若存在嵌套加载状态,可能出现意外行为。
样式化父元素
当父元素包含带 data-loading 的子元素时,用 has-data-loading: 变体样式化父元素:
<div class="has-data-loading:opacity-50">
<button wire:click="save">Save</button>
</div>点击按钮后,整个父级 div 会变为半透明。
样式化兄弟元素
可以用 Tailwind 的 peer 工具配合 peer-data-loading: 变体样式化兄弟元素:
<div>
<button wire:click="save" class="peer">
Save
</button>
<span class="peer-data-loading:opacity-50">
Saving...
</span>
</div>复杂选择器
对于更高级的样式需求,可以用任意变体定位特定元素:
<!-- 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 属性方式有几项优势:
无需指定目标:
wire:loading常常要用wire:target指定响应哪个动作;而data-loading会自动限定在触发请求的那个元素上。样式更优雅:Tailwind 的变体系统能在标记里更干净、声明式地写加载样式。
支持事件:即使派发的事件由其他组件处理,也会加上该属性——这在以前用
wire:loading很难做到。更好组合:用 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 属性:
[data-loading] {
opacity: 0.5;
}
button[data-loading] {
background-color: #ccc;
}也可以用 CSS 样式化子元素:
[data-loading] .loading-text {
display: inline;
}
[data-loading] .default-text {
display: none;
}另请参阅
- wire:loading — 在请求期间显示和隐藏元素
- 动作 — 在动作处理期间展示反馈
- 表单 — 指示表单提交进度
- 懒加载 — 为懒加载组件显示加载状态