# 分销中心Loading优化说明 - v2(微信原生API) ## 一、优化背景 **原实现**:使用自定义loading组件(CSS动画 + WXML结构) **问题**: - 代码冗余,需要维护额外的WXML和CSS - 样式可能与微信小程序原生风格不一致 - 增加了页面复杂度 **优化方案**:使用微信小程序原生API `wx.showLoading()` 和 `wx.hideLoading()` ## 二、优化内容 ### 1. 移除自定义Loading组件 #### WXML修改 (`miniprogram/pages/referral/referral.wxml`) **删除:** ```xml 加载中... ``` **改为:** ```xml ``` #### JS修改 (`miniprogram/pages/referral/referral.js`) **删除data中的isLoading:** ```javascript data: { isLoading: false, // ❌ 删除 // ... } ``` **使用微信原生API:** ```javascript // 初始化数据 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`) **删除:** ```css /* ❌ 删除所有自定义loading样式 */ .loading-overlay { ... } .loading-content { ... } .loading-spinner { ... } @keyframes spin { ... } .loading-text { ... } .content-loading { ... } ``` ## 三、微信原生Loading API详解 ### wx.showLoading(Object) **参数说明:** ```javascript wx.showLoading({ title: '加载中...', // 提示的内容 mask: true, // 是否显示透明蒙层,防止触摸穿透(建议true) success: function() {}, // 接口调用成功的回调函数(可选) fail: function() {}, // 接口调用失败的回调函数(可选) complete: function() {} // 接口调用结束的回调函数(可选) }) ``` **特点:** - ✅ 原生组件,性能优异 - ✅ 自动居中显示 - ✅ 与微信小程序风格统一 - ✅ 自带菊花图(loading icon) - ✅ 支持透明蒙层,防止用户误触 ### wx.hideLoading() **用法:** ```javascript wx.hideLoading() // 无需参数,直接调用 ``` **注意事项:** 1. ⚠️ `wx.showLoading` 和 `wx.hideLoading` 必须配对使用 2. ⚠️ 同一时间只能显示一个loading,多次调用 `wx.showLoading` 会覆盖 3. ⚠️ 如果忘记调用 `wx.hideLoading`,用户会一直看到loading 4. ✅ 建议在 `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. 基本用法 ```javascript 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. 多个异步操作 ```javascript 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. 动态提示文案 ```javascript 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. 防止重复调用 ```javascript 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中关闭 **解决:** ```javascript // ✅ 使用 finally 确保一定关闭 try { // ... } finally { wx.hideLoading() } ``` ### Q2: Loading和Toast冲突? **原因:** `wx.showLoading` 和 `wx.showToast` 互斥,同一时间只能显示一个。 **解决:** ```javascript // ❌ 错误:loading没关闭就显示toast wx.showLoading({ title: '加载中...' }) wx.showToast({ title: '操作成功' }) // 不会显示 // ✅ 正确:先关闭loading再显示toast wx.showLoading({ title: '加载中...' }) await fetchData() wx.hideLoading() wx.showToast({ title: '操作成功' }) ``` ### Q3: 如何自定义Loading样式? **答:** 微信原生Loading不支持自定义样式。如果需要完全自定义样式,可以: 1. 使用自定义组件(本次优化前的方案) 2. 使用第三方UI库(如Vant Weapp) 3. 考虑是否真的需要自定义(推荐使用原生) ### Q4: mask参数有什么用? **答:** `mask: true` 会显示一个透明蒙层,防止用户在loading期间点击其他元素。 ```javascript // ✅ 推荐:防止用户误触 wx.showLoading({ title: '加载中...', mask: true }) // ⚠️ 不推荐:用户可能在加载时误触其他按钮 wx.showLoading({ title: '加载中...', mask: false }) ``` ## 七、总结 ### 优化成果 - ✅ 代码量减少 97%(60行 → 2行) - ✅ 无需维护自定义CSS和WXML - ✅ 性能更优(原生组件) - ✅ 用户体验更好(与微信风格统一) - ✅ 维护成本更低 ### 建议 1. **优先使用微信原生API** - `wx.showLoading()` / `wx.hideLoading()` - `wx.showToast()` - `wx.showModal()` 2. **仅在必要时自定义** - 特殊设计需求 - 品牌强相关的UI - 复杂交互场景 3. **遵循最佳实践** - 使用 `try-finally` 确保loading关闭 - 设置 `mask: true` 防止误触 - 避免loading和toast冲突 --- **优化时间**:2026-02-04 **版本**:v2(微信原生API) **推荐指数**:⭐⭐⭐⭐⭐