GlobalLoading 是基于 wot-design-uni 的 wd-toast 组件封装的全局加载组件,可以结合axios、alova等请求库使用,显示加载状态,通过 Pinia 状态管理实现全局调用,用于显示数据加载、操作处理等场景的等待状态。
wd-toast 组件封装在 App.vue 或根组件中注册:
<template>
<div>
<!-- 其他内容 -->
<GlobalLoading />
</div>
</template>
import { useGlobalLoading } from '@/composables/useGlobalLoading'
const loading = useGlobalLoading()
// 显示加载(字符串参数)
loading.loading('加载中...')
// 显示加载(配置对象)
loading.loading({
msg: '数据加载中',
cover: true
})
// 关闭加载
loading.close()
显示加载状态
// 简单文本
loading.loading('请稍候...')
// 自定义配置
loading.loading({
msg: '数据处理中,请稍候',
cover: false,
position: 'middle'
})
默认配置:
- 图标:loading(旋转动画)
- 持续时间:0(不自动关闭)
- 遮罩:true
- 位置:middle
- 显示:true
关闭加载状态
loading.close()
| 参数 | 类型 | 默认值 | 说明 |
|---|
| msg | string | - | 加载提示文本 |
| iconName | string | 'loading' | 图标名称(固定为loading) |
| duration | number | 0 | 持续时间(ms),0表示不自动关闭 |
| cover | boolean | true | 是否显示遮罩层 |
| position | string | 'middle' | 显示位置:'top' | 'middle' | 'bottom' |
| show | boolean | - | 是否显示(内部使用) |
支持两种参数类型:
export default {
setup() {
const loading = useGlobalLoading()
const handleLoad = async () => {
loading.loading('加载中...')
try {
// 模拟异步操作
await new Promise(resolve => setTimeout(resolve, 2000))
console.log('加载完成')
}
finally {
loading.close()
}
}
return {
handleLoad
}
}
}
async function fetchData() {
const loading = useGlobalLoading()
try {
loading.loading('获取数据中...')
const response = await api.getData()
return response.data
}
catch (error) {
console.error('获取数据失败:', error)
throw error
}
finally {
loading.close()
}
}
async function handleSubmit(formData) {
const loading = useGlobalLoading()
const toast = useGlobalToast()
try {
loading.loading('提交中,请稍候...')
await submitForm(formData)
toast.success('提交成功')
}
catch (error) {
toast.error(`提交失败:${error.message}`)
}
finally {
loading.close()
}
}
async function uploadFile(file) {
const loading = useGlobalLoading()
try {
loading.loading({
msg: '文件上传中...',
cover: true // 防止用户重复操作
})
const result = await uploadToServer(file)
return result
}
finally {
loading.close()
}
}
async function batchProcess(items) {
const loading = useGlobalLoading()
try {
loading.loading(`处理中 (0/${items.length})`)
for (let i = 0; i < items.length; i++) {
// 更新进度提示
loading.loading(`处理中 (${i + 1}/${items.length})`)
await processItem(items[i])
}
}
finally {
loading.close()
}
}
function showCustomLoading() {
loading.loading({
msg: '自定义加载样式',
cover: false, // 不显示遮罩
position: 'top' // 显示在顶部
})
}
loadingOptions(加载配置)、currentPage(当前页面路径)export default {
options: {
virtualHost: true, // 虚拟节点
addGlobalClass: true, // 支持全局样式
styleIsolation: 'shared' // 样式隔离共享
}
}
// ❌ 避免:可能忘记关闭
loading.loading('处理中...')
await doSomething()
loading.close() // 如果上面抛出异常,此行不会执行
```
// 轻量操作,允许用户其他操作
loading.loading({
msg: '加载中...',
cover: false
})
```
// ❌ 模糊不清
loading.loading('请稍候...')
loading.loading('处理中...')
```
长时间操作显示进度
typescript // 对于耗时较长的操作,提供进度信息 for (let i = 0; i < items.length; i++) { loading.loading(`处理进度:${i + 1}/${items.length}`) await processItem(items[i]) }
避免嵌套调用
```typescript
// ❌ 避免嵌套
loading.loading('外层操作...')
await outerOperation()
loading.loading('内层操作...') // 会覆盖外层
await innerOperation()
loading.close() // 只关闭了内层
// ✅ 推荐:合并操作或使用状态管理
loading.loading('正在执行操作...')
try {
await outerOperation()
await innerOperation()
}
finally {
loading.close()
}
```
close()```typescript
// 推荐的错误处理模式
async function safeOperation() {
const loading = useGlobalLoading()
const toast = useGlobalToast()
try {
loading.loading('处理中...')
await riskyOperation()
toast.success('操作成功')
}
catch (error) {
console.error('操作失败:', error)
toast.error('操作失败,请重试')
}
finally {
// 无论成功或失败都要关闭加载
loading.close()
}
}