全局 Loading 使用指南
本项目封装了基于 Pinia 和 wd-toast 的全局 Loading 机制,支持在任何地方(JS/TS 或 Vue 组件)调用。
1. 核心特性
- 全局单例: 依赖 Pinia 状态管理,无需在每个页面引入组件。
- 页面感知: 自动记录调用 Loading 时的页面路径,避免页面切换后 Loading 未关闭的问题。
- 参数灵活: 支持传递字符串(仅显示文字)或对象(自定义图标、遮罩等)。
2. 使用方法
2.1 在 Vue 组件中(setup)
typescript
<script setup lang="ts">
// 1. 引入 useGlobalLoading (已自动导入,可直接使用)
const globalLoading = useGlobalLoading()
async function loadData() {
// 2. 开启 Loading
globalLoading.loading('加载中...')
try {
await apiRequest()
} finally {
// 3. 关闭 Loading
globalLoading.close()
}
}
</script>2.2 在普通 JS/TS 文件中
由于 useGlobalLoading 是 Pinia Store,在 JS 文件中使用时需确保 Pinia 实例已挂载。
typescript
import { useGlobalLoading } from '@/composables/useGlobalLoading'
export function doSomething() {
const globalLoading = useGlobalLoading()
globalLoading.loading({
msg: '处理中...',
duration: 0 // 0 表示一直显示,直到手动关闭
})
}3. API 参数说明
loading(option)
- option:
string|ToastOptions- 如果是
string,则作为msg显示。 - 如果是
ToastOptions对象,支持以下属性:
- 如果是
| 属性名 | 类型 | 默认值 | 说明 |
|---|---|---|---|
msg | string | - | 提示文本 |
iconName | string | 'loading' | 图标名称,默认旋转的 loading 图标 |
duration | number | 0 | 持续时间(ms),0 为手动关闭 |
cover | boolean | true | 是否显示透明遮罩,防止触摸穿透 |
position | string | 'middle' | 显示位置:top/middle/bottom |
close()
关闭当前显示的 Loading。
4. 最佳实践
配合 try/finally 使用: 务必在
finally块中调用close(),确保接口报错也能关闭 Loading。typescriptglobalLoading.loading('请稍候...') try { // 业务逻辑 } catch (e) { // 错误处理 } finally { globalLoading.close() }自动导入: 项目配置了
unplugin-auto-import,在.vue文件中可以直接使用useGlobalLoading(),无需手动 import。
5. 实现原理
- 组件挂载:
<global-loading />组件被放置在src/App.ku.vue中,作为全局根组件的一部分,因此所有页面都能共享。 - 状态管理:
src/composables/useGlobalLoading.ts定义了一个 Pinia Store,管理显示状态和当前页面路径。 - 路由安全: Store 会记录调用时的
currentPage,在 Watcher 中判断,如果页面发生跳转,会自动关闭旧页面的 Loading(视具体实现逻辑而定,目前代码中会校验currentPage === currentPath才显示)。