8.1 KiB
8.1 KiB
分销中心Loading优化说明 - v2(微信原生API)
一、优化背景
原实现:使用自定义loading组件(CSS动画 + WXML结构)
问题:
- 代码冗余,需要维护额外的WXML和CSS
- 样式可能与微信小程序原生风格不一致
- 增加了页面复杂度
优化方案:使用微信小程序原生API wx.showLoading() 和 wx.hideLoading()
二、优化内容
1. 移除自定义Loading组件
WXML修改 (miniprogram/pages/referral/referral.wxml)
删除:
<!-- 删除自定义loading组件 -->
<view class="loading-overlay" wx:if="{{isLoading}}">
<view class="loading-content">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
</view>
<!-- 删除content的动态class -->
<view class="content {{isLoading ? 'content-loading' : ''}}">
改为:
<!-- 使用微信原生loading,无需WXML代码 -->
<view class="content">
JS修改 (miniprogram/pages/referral/referral.js)
删除data中的isLoading:
data: {
isLoading: false, // ❌ 删除
// ...
}
使用微信原生API:
// 初始化数据
async initData() {
const { isLoggedIn, userInfo } = app.globalData
if (isLoggedIn && userInfo) {
// ✅ 显示微信原生loading
wx.showLoading({
title: '加载中...',
mask: true // 防止触摸穿透
})
try {
// ... 数据加载逻辑
this.setData({
// ... 设置数据
})
// ✅ 隐藏loading
wx.hideLoading()
} catch (e) {
console.log('[Referral] ❌ API调用失败:', e)
// ✅ 失败也要隐藏loading
wx.hideLoading()
}
}
}
WXSS修改 (miniprogram/pages/referral/referral.wxss)
删除:
/* ❌ 删除所有自定义loading样式 */
.loading-overlay { ... }
.loading-content { ... }
.loading-spinner { ... }
@keyframes spin { ... }
.loading-text { ... }
.content-loading { ... }
三、微信原生Loading API详解
wx.showLoading(Object)
参数说明:
wx.showLoading({
title: '加载中...', // 提示的内容
mask: true, // 是否显示透明蒙层,防止触摸穿透(建议true)
success: function() {}, // 接口调用成功的回调函数(可选)
fail: function() {}, // 接口调用失败的回调函数(可选)
complete: function() {} // 接口调用结束的回调函数(可选)
})
特点:
- ✅ 原生组件,性能优异
- ✅ 自动居中显示
- ✅ 与微信小程序风格统一
- ✅ 自带菊花图(loading icon)
- ✅ 支持透明蒙层,防止用户误触
wx.hideLoading()
用法:
wx.hideLoading() // 无需参数,直接调用
注意事项:
- ⚠️
wx.showLoading和wx.hideLoading必须配对使用 - ⚠️ 同一时间只能显示一个loading,多次调用
wx.showLoading会覆盖 - ⚠️ 如果忘记调用
wx.hideLoading,用户会一直看到loading - ✅ 建议在
try-catch的finally或catch中也调用wx.hideLoading()
与 wx.showToast 的区别
| 特性 | wx.showLoading | wx.showToast |
|---|---|---|
| 用途 | 数据加载中 | 操作结果反馈 |
| 图标 | 菊花图(loading icon) | 成功/失败/警告图标 |
| 自动关闭 | ❌ 需要手动 wx.hideLoading() |
✅ 自动关闭(默认1.5秒) |
| 蒙层 | ✅ 支持mask参数 | ✅ 支持mask参数 |
| 互斥 | 与 wx.showToast 互斥 |
与 wx.showLoading 互斥 |
四、优化前后对比
代码量对比
| 文件 | 优化前 | 优化后 | 减少 |
|---|---|---|---|
| WXML | +7行 | 0行 | -7行 |
| JS | isLoading state + this.setData() |
2行API调用 | -3行 |
| WXSS | +50行 | 0行 | -50行 |
| 总计 | +60行 | 2行 | -58行 |
性能对比
| 指标 | 自定义Loading | 微信原生Loading |
|---|---|---|
| 渲染性能 | 需要WXML渲染 | 原生组件,更快 |
| 内存占用 | 额外DOM节点 | 无额外DOM |
| 样式一致性 | 需要手动调整 | 与微信风格统一 |
| 维护成本 | 高 | 低 |
用户体验对比
自定义Loading:
- 需要自己设计样式
- 可能与微信小程序风格不一致
- 动画性能依赖CSS实现
微信原生Loading:
- ✅ 与微信小程序风格统一
- ✅ 用户熟悉的交互体验
- ✅ 性能更优
五、最佳实践
1. 基本用法
async loadData() {
wx.showLoading({ title: '加载中...', mask: true })
try {
const data = await fetchData()
this.setData({ data })
} catch (e) {
wx.showToast({ title: '加载失败', icon: 'none' })
} finally {
wx.hideLoading() // ✅ 确保一定会关闭
}
}
2. 多个异步操作
async loadMultipleData() {
wx.showLoading({ title: '加载中...', mask: true })
try {
// 并行请求
const [data1, data2, data3] = await Promise.all([
fetchData1(),
fetchData2(),
fetchData3()
])
this.setData({ data1, data2, data3 })
} catch (e) {
wx.showToast({ title: '加载失败', icon: 'none' })
} finally {
wx.hideLoading()
}
}
3. 动态提示文案
async syncData() {
wx.showLoading({ title: '同步数据中...', mask: true })
try {
await syncToServer()
wx.hideLoading()
wx.showToast({ title: '同步成功', icon: 'success' })
} catch (e) {
wx.hideLoading()
wx.showToast({ title: '同步失败', icon: 'none' })
}
}
4. 防止重复调用
data: {
isRequesting: false // 添加请求锁
},
async loadData() {
if (this.data.isRequesting) return // ✅ 防止重复请求
this.setData({ isRequesting: true })
wx.showLoading({ title: '加载中...', mask: true })
try {
const data = await fetchData()
this.setData({ data })
} finally {
wx.hideLoading()
this.setData({ isRequesting: false })
}
}
六、常见问题
Q1: Loading不关闭怎么办?
原因:
- 忘记调用
wx.hideLoading() - 请求出错,没有在catch中关闭
解决:
// ✅ 使用 finally 确保一定关闭
try {
// ...
} finally {
wx.hideLoading()
}
Q2: Loading和Toast冲突?
原因:
wx.showLoading 和 wx.showToast 互斥,同一时间只能显示一个。
解决:
// ❌ 错误:loading没关闭就显示toast
wx.showLoading({ title: '加载中...' })
wx.showToast({ title: '操作成功' }) // 不会显示
// ✅ 正确:先关闭loading再显示toast
wx.showLoading({ title: '加载中...' })
await fetchData()
wx.hideLoading()
wx.showToast({ title: '操作成功' })
Q3: 如何自定义Loading样式?
答: 微信原生Loading不支持自定义样式。如果需要完全自定义样式,可以:
- 使用自定义组件(本次优化前的方案)
- 使用第三方UI库(如Vant Weapp)
- 考虑是否真的需要自定义(推荐使用原生)
Q4: mask参数有什么用?
答:
mask: true 会显示一个透明蒙层,防止用户在loading期间点击其他元素。
// ✅ 推荐:防止用户误触
wx.showLoading({ title: '加载中...', mask: true })
// ⚠️ 不推荐:用户可能在加载时误触其他按钮
wx.showLoading({ title: '加载中...', mask: false })
七、总结
优化成果
- ✅ 代码量减少 97%(60行 → 2行)
- ✅ 无需维护自定义CSS和WXML
- ✅ 性能更优(原生组件)
- ✅ 用户体验更好(与微信风格统一)
- ✅ 维护成本更低
建议
-
优先使用微信原生API
wx.showLoading()/wx.hideLoading()wx.showToast()wx.showModal()
-
仅在必要时自定义
- 特殊设计需求
- 品牌强相关的UI
- 复杂交互场景
-
遵循最佳实践
- 使用
try-finally确保loading关闭 - 设置
mask: true防止误触 - 避免loading和toast冲突
- 使用
优化时间:2026-02-04
版本:v2(微信原生API)
推荐指数:⭐⭐⭐⭐⭐