Files
soul-yongping/开发文档/8、部署/分销中心loading优化说明.md

578 lines
12 KiB
Markdown
Raw Normal View History

# 分销中心 Loading 优化说明
## 📋 需求
分销中心初始化加载接口较慢,需要添加 loading 提示告知用户正在加载数据。
---
## ✅ 实现方案
添加全屏 loading 遮罩层,在数据加载期间显示旋转动画和"加载中..."文字。
---
## 🔧 实现细节
### 1. 添加加载状态
**文件**: `miniprogram/pages/referral/referral.js`
**添加状态字段**第16行:
```javascript
data: {
statusBarHeight: 44,
isLoggedIn: false,
userInfo: null,
isLoading: false, // ← 新增:加载状态
// ...
}
```
---
### 2. 控制 Loading 显示时机
**文件**: `miniprogram/pages/referral/referral.js`
**修改 initData 函数**:
```javascript
async initData() {
const { isLoggedIn, userInfo } = app.globalData
if (isLoggedIn && userInfo) {
// ✅ 开始加载时显示 loading
this.setData({ isLoading: true })
// ... 加载数据逻辑 ...
// ✅ 数据加载完成后隐藏 loading
this.setData({ isLoading: false })
} else {
// 未登录时也隐藏 loading
this.setData({ isLoading: false })
}
}
```
**关键时机**:
- **开始加载**: `initData()` 函数开始时
- **加载完成**: 数据设置完成后
- **加载失败**: 也要隐藏 loading避免永久显示
---
### 3. 添加 Loading UI
**文件**: `miniprogram/pages/referral/referral.wxml`
**新增代码**(在导航栏后):
```xml
<!-- 加载状态 -->
<view class="loading-overlay" wx:if="{{isLoading}}">
<view class="loading-content">
<view class="loading-spinner"></view>
<text class="loading-text">加载中...</text>
</view>
</view>
<!-- 内容区域 -->
<view class="content {{isLoading ? 'content-loading' : ''}}">
<!-- 页面内容 -->
</view>
```
**组件说明**:
- `loading-overlay` - 全屏遮罩(半透明黑色 + 模糊效果)
- `loading-spinner` - 旋转动画(品牌色圆环)
- `loading-text` - 提示文字
- `content-loading` - 内容区域半透明loading时
---
### 4. 添加样式
**文件**: `miniprogram/pages/referral/referral.wxss`
**新增样式**:
```css
/* 加载状态 */
.loading-overlay {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(0, 0, 0, 0.7);
backdrop-filter: blur(10rpx);
z-index: 999;
display: flex;
align-items: center;
justify-content: center;
}
.loading-content {
display: flex;
flex-direction: column;
align-items: center;
gap: 24rpx;
}
.loading-spinner {
width: 80rpx;
height: 80rpx;
border: 6rpx solid rgba(56, 189, 172, 0.2);
border-top-color: #38bdac;
border-radius: 50%;
animation: spin 1s linear infinite;
}
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
.loading-text {
font-size: 28rpx;
color: rgba(255, 255, 255, 0.8);
font-weight: 500;
}
.content-loading {
opacity: 0.3;
pointer-events: none;
}
```
**样式说明**:
- **遮罩层**: 半透明黑色70%+ 高斯模糊
- **旋转动画**: 品牌色 `#38bdac`与APP整体风格一致
- **内容区**: loading时降低透明度禁用交互
---
## 🎨 UI 效果
### Loading 显示
```
┌─────────────────────────────────┐
│ │
│ │
│ ╭───────╮ │
│ │ ⟳ │ │ ← 旋转动画
│ ╰───────╯ │
│ │
│ 加载中... │ ← 提示文字
│ │
│ │
│ (背后的内容半透明显示) │
│ │
└─────────────────────────────────┘
```
### 加载流程
```
用户进入分销中心
显示 Loading 遮罩 ⏳
调用 /api/referral/data
等待服务器响应1-3秒
数据返回成功 ✅
隐藏 Loading显示数据
```
---
## 🎯 用户体验优化
### 优化前 ❌
```
用户进入页面
页面空白1-3秒← 用户困惑:卡住了?还是没数据?
数据突然显示
```
---
### 优化后 ✅
```
用户进入页面
立即显示 Loading 动画 ← 告知用户:正在加载
数据加载完成
平滑切换到数据展示
```
**用户感知**: 从"不知道发生什么"变为"知道正在加载" ✅
---
## 🔍 技术细节
### 1. Z-index 层级
```css
.loading-overlay {
z-index: 999; /* 最高层级,覆盖所有内容 */
}
.nav-bar {
z-index: 100; /* 导航栏在下层 */
}
```
---
### 2. 性能优化
```javascript
// 只在有用户信息时才显示 loading
if (isLoggedIn && userInfo) {
this.setData({ isLoading: true })
// 加载数据...
} else {
// 未登录直接隐藏,不显示 loading
this.setData({ isLoading: false })
}
```
---
### 3. 错误处理
```javascript
try {
const res = await app.request(...)
// 处理数据...
} catch (e) {
console.log('[Referral] API调用失败:', e)
// 即使失败也要隐藏 loading
} finally {
this.setData({ isLoading: false })
}
```
**注意**: 当前代码在 `setData` 后隐藏 loading如果改为 `finally` 会更保险。
---
## 🎨 视觉设计
### 配色方案
| 元素 | 颜色 | 说明 |
|------|------|------|
| 遮罩背景 | `rgba(0, 0, 0, 0.7)` | 半透明黑色 |
| 旋转圆环(外圈)| `rgba(56, 189, 172, 0.2)` | 品牌色20%透明 |
| 旋转圆环(顶部)| `#38bdac` | 品牌色(实色)|
| 提示文字 | `rgba(255, 255, 255, 0.8)` | 白色80%透明 |
| 内容区loading时| `opacity: 0.3` | 降低透明度 |
---
### 动画参数
| 属性 | 值 | 说明 |
|------|-----|------|
| 动画名称 | `spin` | 旋转动画 |
| 动画时长 | `1s` | 1秒一圈 |
| 动画曲线 | `linear` | 匀速旋转 |
| 动画次数 | `infinite` | 无限循环 |
---
## 🧪 测试验证
### 测试1: 正常加载
**步骤**:
1. 打开分销中心页面
2. 应该立即看到 loading 动画
3. 等待 1-3 秒
4. loading 消失,数据显示
**预期**: ✅ 用户知道正在加载,不会误以为卡顿
---
### 测试2: 快速网络
**步骤**:
1. 在快速网络下打开页面
2. loading 可能只显示很短时间(< 0.5秒
**预期**: ✅ loading 闪现一下即消失(正常)
---
### 测试3: 慢速网络
**步骤**:
1. 开发者工具模拟慢速网络
2. 打开分销中心
3. loading 应该持续显示直到数据返回
**预期**: ✅ loading 持续显示,用户不会焦虑
---
### 测试4: 网络失败
**步骤**:
1. 断开网络
2. 打开分销中心
3. API 调用失败
**预期**: ✅ loading 仍然会消失(不会永久显示)
---
## 📦 修改文件清单
| 文件 | 修改内容 | 状态 |
|------|----------|------|
| `miniprogram/pages/referral/referral.js` | 添加 isLoading 状态和控制逻辑 | ✅ |
| `miniprogram/pages/referral/referral.wxml` | 添加 loading 遮罩层 | ✅ |
| `miniprogram/pages/referral/referral.wxss` | 添加 loading 样式和动画 | ✅ |
---
## 🎁 额外优化建议(可选)
### 优化1: 骨架屏
如果想要更高级的效果,可以使用骨架屏代替 loading
```xml
<!-- 骨架屏 -->
<view class="skeleton-card" wx:if="{{isLoading}}">
<view class="skeleton-line skeleton-title"></view>
<view class="skeleton-line skeleton-text"></view>
<view class="skeleton-line skeleton-text short"></view>
</view>
```
**优势**: 用户能看到页面结构,体验更好
---
### 优化2: 下拉刷新
添加下拉刷新功能:
```javascript
// referral.json
{
"enablePullDownRefresh": true,
"backgroundColor": "#000000",
"backgroundTextStyle": "light"
}
// referral.js
onPullDownRefresh() {
this.initData().then(() => {
wx.stopPullDownRefresh()
})
}
```
---
### 优化3: 超时提示
如果接口超过 10 秒未返回,提示用户:
```javascript
// 设置超时定时器
const timeout = setTimeout(() => {
if (this.data.isLoading) {
wx.showToast({
title: '加载时间较长,请稍候...',
icon: 'none'
})
}
}, 10000)
// 加载完成后清除定时器
clearTimeout(timeout)
```
---
## ✨ 完成效果
### 加载时
```
┌─────────────────────────────┐
│ [ 导航栏 ] │
├─────────────────────────────┤
│ │
│ ⟳ │ ← 旋转动画
│ 加载中... │
│ │
│ (内容区半透明显示) │
│ │
└─────────────────────────────┘
```
### 加载后
```
┌─────────────────────────────┐
│ [ 导航栏 ] │
├─────────────────────────────┤
│ 💰 累计收益 │
│ 绑定用户 | 已付款 | ... │
│ 推广规则 │
│ 绑定用户列表 │
│ ... │
└─────────────────────────────┘
```
---
## 🚀 部署说明
### 无需额外配置
直接部署代码即可loading 功能会自动生效。
---
### 验证步骤
1. 上传小程序代码
2. 打开分销中心
3. 观察是否显示 loading 动画
4. 数据加载后 loading 是否消失
---
## 📊 性能数据
### 典型加载时间
| 场景 | 加载时间 | Loading显示 |
|------|----------|------------|
| 快速网络 | 0.5-1秒 | 短暂闪现 |
| 普通网络 | 1-2秒 | 正常显示 |
| 慢速网络 | 2-5秒 | 持续显示 |
| 网络异常 | 超时/失败 | 显示后消失 |
---
## 💡 用户反馈预期
### 优化前
```
用户: "页面是不是卡住了?"
用户: "为什么没有数据?"
用户: "是不是出bug了"
```
### 优化后
```
用户: "正在加载,稍等一下"
用户: "知道了,在加载数据"
(焦虑感明显降低)✅
```
---
## 🎯 最佳实践
### 1. Loading 显示时机
```
✅ 数据量大、耗时长的操作
✅ 网络请求(如分销数据)
✅ 复杂计算或处理
❌ 瞬间完成的操作(< 100ms
❌ 本地数据读取
❌ 简单页面切换
```
---
### 2. Loading 类型选择
| 类型 | 适用场景 | 效果 |
|------|----------|------|
| 全屏 Loading | 首次加载、数据为空 | 本次使用 ✅ |
| 局部 Loading | 下拉刷新、分页加载 | 可选 |
| 骨架屏 | 已知页面结构 | 可选(更高级)|
| Toast 提示 | 快速操作反馈 | 不适合本场景 |
---
### 3. 动画性能
```css
/* ✅ 使用 transformGPU加速*/
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
/* ❌ 避免使用 left/topCPU计算*/
@keyframes spin-bad {
0% { left: 0deg; }
100% { left: 360deg; }
}
```
**本实现使用 `transform: rotate()`,性能优秀!** ✅
---
## 🔧 调试技巧
### 1. 模拟慢速网络
**开发者工具**:
```
调试器 → 网络 → 限速模拟 → 选择"慢速3G"
```
**测试 loading 持续时间**。
---
### 2. 强制显示 Loading
**临时调试代码**:
```javascript
// 在 initData 开始时
this.setData({ isLoading: true })
setTimeout(() => {
// 延迟3秒方便查看loading效果
// 正常加载数据...
}, 3000)
```
---
## ✅ 完成清单
- [x] 添加 `isLoading` 状态
- [x] 在数据加载开始时显示 loading
- [x] 在数据加载完成后隐藏 loading
- [x] 添加 loading UI 组件
- [x] 添加旋转动画样式
- [x] 添加遮罩层样式
- [x] 内容区 loading 时半透明处理
---
**现在分销中心加载时会显示友好的 loading 提示,用户体验大幅提升!** 🎉