433 lines
9.0 KiB
Markdown
433 lines
9.0 KiB
Markdown
|
|
# 新用户引导功能说明
|
|||
|
|
|
|||
|
|
## 功能概述
|
|||
|
|
|
|||
|
|
为首页添加了新用户引导功能,首次访问小程序时会自动显示,帮助用户快速了解核心功能。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 技术实现
|
|||
|
|
|
|||
|
|
### 1. 引导组件 (`components/guide/guide`)
|
|||
|
|
|
|||
|
|
**核心特性**:
|
|||
|
|
- ✅ 高亮遮罩层(打洞效果)
|
|||
|
|
- ✅ 自适应位置计算
|
|||
|
|
- ✅ 多步骤引导流程
|
|||
|
|
- ✅ 进度指示器
|
|||
|
|
- ✅ 平滑过渡动画
|
|||
|
|
- ✅ 防止穿透交互
|
|||
|
|
|
|||
|
|
**文件结构**:
|
|||
|
|
```
|
|||
|
|
components/guide/
|
|||
|
|
├── guide.wxml # 模板(遮罩 + 高亮 + 提示卡片)
|
|||
|
|
├── guide.wxss # 样式(渐变背景 + 动画)
|
|||
|
|
├── guide.js # 逻辑(位置计算 + 步骤控制)
|
|||
|
|
└── guide.json # 配置
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 引导步骤配置
|
|||
|
|
|
|||
|
|
在 [pages/index/index.js](pages/index/index.js) 中定义引导步骤:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
guideSteps: [
|
|||
|
|
{
|
|||
|
|
selector: '.guide-create-btn', // 目标元素选择器
|
|||
|
|
title: '创建房间', // 标题
|
|||
|
|
description: '点击这里可以...', // 说明文字
|
|||
|
|
position: 'bottom', // 提示框位置(top/bottom/left/right)
|
|||
|
|
padding: 12, // 高亮区域扩展边距
|
|||
|
|
borderRadius: 16 // 高亮区域圆角
|
|||
|
|
},
|
|||
|
|
// ... 更多步骤
|
|||
|
|
]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 首次访问检测
|
|||
|
|
|
|||
|
|
使用 `wx.getStorageSync('hasShownGuide')` 检测是否已显示过引导:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
checkAndShowGuide() {
|
|||
|
|
const hasShownGuide = wx.getStorageSync('hasShownGuide')
|
|||
|
|
if (!hasShownGuide) {
|
|||
|
|
// 延迟500ms显示,等待页面完全渲染
|
|||
|
|
setTimeout(() => {
|
|||
|
|
this.setData({ showGuide: true })
|
|||
|
|
}, 500)
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 4. 目标元素标记
|
|||
|
|
|
|||
|
|
为需要引导的元素添加唯一的class:
|
|||
|
|
|
|||
|
|
```html
|
|||
|
|
<!-- 创建房间按钮 -->
|
|||
|
|
<view class="action-btn primary-btn guide-create-btn" bindtap="createRoom">
|
|||
|
|
<!-- ... -->
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 加入房间按钮 -->
|
|||
|
|
<view class="action-btn secondary-btn guide-join-btn" bindtap="joinRoom">
|
|||
|
|
<!-- ... -->
|
|||
|
|
</view>
|
|||
|
|
|
|||
|
|
<!-- 扫码按钮 -->
|
|||
|
|
<view class="scan-btn guide-scan-btn" bindtap="scanCode">
|
|||
|
|
<!-- ... -->
|
|||
|
|
</view>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 使用方式
|
|||
|
|
|
|||
|
|
### 在其他页面中使用
|
|||
|
|
|
|||
|
|
#### 1. 注册组件
|
|||
|
|
|
|||
|
|
在页面的 `xxx.json` 中:
|
|||
|
|
|
|||
|
|
```json
|
|||
|
|
{
|
|||
|
|
"usingComponents": {
|
|||
|
|
"user-guide": "../../components/guide/guide"
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 2. 添加模板
|
|||
|
|
|
|||
|
|
在页面的 `xxx.wxml` 中:
|
|||
|
|
|
|||
|
|
```html
|
|||
|
|
<user-guide
|
|||
|
|
show="{{showGuide}}"
|
|||
|
|
steps="{{guideSteps}}"
|
|||
|
|
bind:complete="onGuideComplete"
|
|||
|
|
/>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
#### 3. 配置步骤
|
|||
|
|
|
|||
|
|
在页面的 `xxx.js` 中:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
Page({
|
|||
|
|
data: {
|
|||
|
|
showGuide: false,
|
|||
|
|
guideSteps: [
|
|||
|
|
{
|
|||
|
|
selector: '.target-element',
|
|||
|
|
title: '功能标题',
|
|||
|
|
description: '功能说明文字',
|
|||
|
|
position: 'bottom', // 可选:top/bottom/left/right
|
|||
|
|
padding: 12, // 可选:高亮区域扩展边距(默认8)
|
|||
|
|
borderRadius: 16, // 可选:圆角大小(默认16)
|
|||
|
|
showArrow: true // 可选:是否显示箭头(默认true)
|
|||
|
|
}
|
|||
|
|
// ... 更多步骤
|
|||
|
|
]
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onReady() {
|
|||
|
|
// 检查是否需要显示引导
|
|||
|
|
const hasShown = wx.getStorageSync('hasShownGuide_pageName')
|
|||
|
|
if (!hasShown) {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
this.setData({ showGuide: true })
|
|||
|
|
}, 500)
|
|||
|
|
}
|
|||
|
|
},
|
|||
|
|
|
|||
|
|
onGuideComplete() {
|
|||
|
|
this.setData({ showGuide: false })
|
|||
|
|
wx.setStorageSync('hasShownGuide_pageName', true)
|
|||
|
|
}
|
|||
|
|
})
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 测试方法
|
|||
|
|
|
|||
|
|
### 方法1:清除存储测试
|
|||
|
|
|
|||
|
|
在微信开发者工具的控制台中执行:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 清除引导标记
|
|||
|
|
wx.removeStorageSync('hasShownGuide')
|
|||
|
|
|
|||
|
|
// 重新加载页面
|
|||
|
|
wx.reLaunch({ url: '/pages/index/index' })
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 方法2:清除缓存测试
|
|||
|
|
|
|||
|
|
1. 微信开发者工具 → 清缓存 → 清除所有
|
|||
|
|
2. 重新编译项目
|
|||
|
|
3. 重新进入首页
|
|||
|
|
|
|||
|
|
### 方法3:手动触发测试
|
|||
|
|
|
|||
|
|
在 [pages/index/index.js](pages/index/index.js) 中临时修改:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
checkAndShowGuide() {
|
|||
|
|
// 注释掉检查逻辑,直接显示
|
|||
|
|
// const hasShownGuide = wx.getStorageSync('hasShownGuide')
|
|||
|
|
// if (!hasShownGuide) {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
this.setData({ showGuide: true })
|
|||
|
|
}, 500)
|
|||
|
|
// }
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 自定义配置
|
|||
|
|
|
|||
|
|
### 修改引导步骤
|
|||
|
|
|
|||
|
|
编辑 [pages/index/index.js](pages/index/index.js) 中的 `guideSteps` 数组:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
guideSteps: [
|
|||
|
|
// 添加新的步骤
|
|||
|
|
{
|
|||
|
|
selector: '.my-element',
|
|||
|
|
title: '新功能',
|
|||
|
|
description: '这是一个新功能的说明',
|
|||
|
|
position: 'top',
|
|||
|
|
padding: 10,
|
|||
|
|
borderRadius: 12
|
|||
|
|
}
|
|||
|
|
]
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 修改样式
|
|||
|
|
|
|||
|
|
编辑 [components/guide/guide.wxss](components/guide/guide.wxss):
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
/* 修改遮罩透明度 */
|
|||
|
|
.guide-overlay {
|
|||
|
|
background: rgba(0, 0, 0, 0.75); /* 调整透明度 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 修改提示卡片样式 */
|
|||
|
|
.guide-text-wrapper {
|
|||
|
|
background: white; /* 背景色 */
|
|||
|
|
border-radius: 16rpx; /* 圆角 */
|
|||
|
|
padding: 32rpx 28rpx; /* 内边距 */
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
/* 修改按钮样式 */
|
|||
|
|
.guide-next {
|
|||
|
|
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 修改位置计算逻辑
|
|||
|
|
|
|||
|
|
编辑 [components/guide/guide.js](components/guide/guide.js) 中的 `calculateContentPosition` 方法。
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 功能特点
|
|||
|
|
|
|||
|
|
### 1. 智能位置计算
|
|||
|
|
|
|||
|
|
组件会自动计算最佳显示位置,避免超出屏幕边界:
|
|||
|
|
|
|||
|
|
- 优先使用指定位置(top/bottom/left/right)
|
|||
|
|
- 空间不足时自动切换到对面
|
|||
|
|
- 保持在屏幕可视范围内
|
|||
|
|
|
|||
|
|
### 2. 高亮打洞效果
|
|||
|
|
|
|||
|
|
使用 CSS `box-shadow` 实现高亮区域:
|
|||
|
|
|
|||
|
|
```css
|
|||
|
|
.guide-spotlight {
|
|||
|
|
box-shadow: 0 0 0 9999px rgba(0, 0, 0, 0.75);
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
这样可以在遮罩层上"打洞",突出显示目标元素。
|
|||
|
|
|
|||
|
|
### 3. 步骤进度指示
|
|||
|
|
|
|||
|
|
底部圆点显示当前进度:
|
|||
|
|
|
|||
|
|
- 灰色圆点:未完成的步骤
|
|||
|
|
- 紫色长条:当前步骤
|
|||
|
|
- 平滑过渡动画
|
|||
|
|
|
|||
|
|
### 4. 防止交互穿透
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 阻止滚动
|
|||
|
|
preventMove() {}
|
|||
|
|
|
|||
|
|
// 阻止点击穿透
|
|||
|
|
catchtouchmove="preventMove"
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 注意事项
|
|||
|
|
|
|||
|
|
### 1. 选择器必须唯一
|
|||
|
|
|
|||
|
|
确保每个引导步骤的 `selector` 能唯一定位到目标元素:
|
|||
|
|
|
|||
|
|
```html
|
|||
|
|
<!-- ✅ 正确:使用唯一的class -->
|
|||
|
|
<view class="btn guide-create-btn"></view>
|
|||
|
|
|
|||
|
|
<!-- ❌ 错误:选择器不唯一 -->
|
|||
|
|
<view class="btn"></view>
|
|||
|
|
<view class="btn"></view>
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 2. 等待页面渲染
|
|||
|
|
|
|||
|
|
在 `onReady` 生命周期中显示引导,并使用延迟:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
onReady() {
|
|||
|
|
setTimeout(() => {
|
|||
|
|
this.setData({ showGuide: true })
|
|||
|
|
}, 500) // 延迟500ms,确保页面完全渲染
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### 3. 避免在隐藏元素上使用
|
|||
|
|
|
|||
|
|
不要在 `wx:if="{{false}}"` 或 `display: none` 的元素上使用引导,否则无法获取位置。
|
|||
|
|
|
|||
|
|
### 4. 不同页面使用不同标记
|
|||
|
|
|
|||
|
|
如果多个页面都有引导,使用不同的storage key:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
// 首页
|
|||
|
|
wx.setStorageSync('hasShownGuide_index', true)
|
|||
|
|
|
|||
|
|
// 其他页面
|
|||
|
|
wx.setStorageSync('hasShownGuide_detail', true)
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## API参数
|
|||
|
|
|
|||
|
|
### 组件属性
|
|||
|
|
|
|||
|
|
| 属性 | 类型 | 必需 | 默认值 | 说明 |
|
|||
|
|
|------|------|------|--------|------|
|
|||
|
|
| show | Boolean | 是 | false | 是否显示引导 |
|
|||
|
|
| steps | Array | 是 | [] | 引导步骤配置 |
|
|||
|
|
|
|||
|
|
### 组件事件
|
|||
|
|
|
|||
|
|
| 事件 | 参数 | 说明 |
|
|||
|
|
|------|------|------|
|
|||
|
|
| complete | 无 | 引导完成时触发 |
|
|||
|
|
|
|||
|
|
### 步骤配置
|
|||
|
|
|
|||
|
|
| 字段 | 类型 | 必需 | 默认值 | 说明 |
|
|||
|
|
|------|------|------|--------|------|
|
|||
|
|
| selector | String | 是 | - | 目标元素的CSS选择器 |
|
|||
|
|
| title | String | 是 | - | 引导标题 |
|
|||
|
|
| description | String | 是 | - | 引导说明文字 |
|
|||
|
|
| position | String | 否 | 'bottom' | 提示框位置(top/bottom/left/right)|
|
|||
|
|
| padding | Number | 否 | 8 | 高亮区域扩展边距(px)|
|
|||
|
|
| borderRadius | Number | 否 | 16 | 高亮区域圆角大小(px)|
|
|||
|
|
| showArrow | Boolean | 否 | true | 是否显示箭头 |
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 效果预览
|
|||
|
|
|
|||
|
|
### 步骤1:创建房间
|
|||
|
|
- 高亮"创建房间"按钮
|
|||
|
|
- 显示说明文字
|
|||
|
|
- 进度指示:1/3
|
|||
|
|
|
|||
|
|
### 步骤2:加入房间
|
|||
|
|
- 高亮"加入房间"按钮
|
|||
|
|
- 显示说明文字
|
|||
|
|
- 进度指示:2/3
|
|||
|
|
|
|||
|
|
### 步骤3:扫码进入
|
|||
|
|
- 高亮"扫码"按钮
|
|||
|
|
- 显示说明文字
|
|||
|
|
- 进度指示:3/3
|
|||
|
|
- 显示"知道了"按钮
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 常见问题
|
|||
|
|
|
|||
|
|
### Q: 引导没有显示?
|
|||
|
|
|
|||
|
|
A: 检查以下几点:
|
|||
|
|
1. 是否已经显示过(清除 storage)
|
|||
|
|
2. 选择器是否正确
|
|||
|
|
3. 目标元素是否已渲染
|
|||
|
|
4. 延迟时间是否足够
|
|||
|
|
|
|||
|
|
### Q: 位置显示不对?
|
|||
|
|
|
|||
|
|
A: 检查:
|
|||
|
|
1. 目标元素是否被隐藏
|
|||
|
|
2. 页面是否完全渲染
|
|||
|
|
3. 增加 `setTimeout` 延迟时间
|
|||
|
|
|
|||
|
|
### Q: 如何调试?
|
|||
|
|
|
|||
|
|
A: 在组件的 `showStep` 方法中添加日志:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
showStep(stepIndex) {
|
|||
|
|
const step = this.data.steps[stepIndex]
|
|||
|
|
console.log('显示引导步骤:', stepIndex, step)
|
|||
|
|
// ...
|
|||
|
|
}
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
### Q: 如何强制重新显示引导?
|
|||
|
|
|
|||
|
|
A: 控制台执行:
|
|||
|
|
|
|||
|
|
```javascript
|
|||
|
|
wx.removeStorageSync('hasShownGuide')
|
|||
|
|
getCurrentPages()[0].setData({ showGuide: true })
|
|||
|
|
```
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 未来优化方向
|
|||
|
|
|
|||
|
|
1. **手势控制** - 支持滑动切换步骤
|
|||
|
|
2. **视频教程** - 嵌入视频演示
|
|||
|
|
3. **自定义主题** - 支持暗色模式
|
|||
|
|
4. **动画增强** - 添加更多过渡动画
|
|||
|
|
5. **智能触发** - 根据用户行为动态显示引导
|
|||
|
|
6. **A/B测试** - 支持多种引导方案
|
|||
|
|
|
|||
|
|
---
|
|||
|
|
|
|||
|
|
## 开发者
|
|||
|
|
|
|||
|
|
如有问题或建议,请联系开发团队。
|