更新记录
1.0.0(2025-11-17) 下载此版本
平台兼容性
uni-app(3.6.14)
| Vue2 | Vue2插件版本 | Vue3 | Vue2插件版本 | Chrome | Chrome插件版本 | Safari | Safari插件版本 | app-vue | app-vue插件版本 | app-nvue | app-nvue插件版本 | Android | Android插件版本 | iOS | iOS插件版本 | 鸿蒙 | 鸿蒙插件版本 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | 5.0 | 1.0.0 | 12 | 1.0.0 | √ | 1.0.0 |
| 微信小程序 | 微信小程序插件版本 | 支付宝小程序 | 支付宝小程序插件版本 | 抖音小程序 | 抖音小程序插件版本 | 百度小程序 | 百度小程序插件版本 | 快手小程序 | 快手小程序插件版本 | 京东小程序 | 京东小程序插件版本 | 鸿蒙元服务 | 鸿蒙元服务插件版本 | QQ小程序 | QQ小程序插件版本 | 飞书小程序 | 飞书小程序插件版本 | 快应用-华为 | 快应用-华为插件版本 | 快应用-联盟 | 快应用-联盟插件版本 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 | √ | 1.0.0 |
uni-app x(3.6.14)
| Chrome | Safari | Android | iOS | 鸿蒙 | 微信小程序 |
|---|---|---|---|---|---|
| - | - | - | - | - | - |
其他
| 多语言 | 暗黑模式 | 宽屏模式 |
|---|---|---|
| √ | √ | √ |
hy-interactive-tour
🎯 应用内引导 + 高亮遮罩 + 聚焦指示器插件
让用户轻松上手你的应用,就像 App Store 的应用引导一样!
✨ 特性
🌈 核心功能
- ✅ 跨平台支持:完美兼容 H5、小程序(微信/支付宝/抖音/百度/QQ)、App(iOS/Android)、uni-app x
- ✅ 智能高亮:支持矩形、圆形、圆角矩形三种高亮形状,自动适配元素大小
- ✅ 自动滚动:目标元素自动滚动到可视区域,支持平滑滚动动画
- ✅ 智能定位:提示框自动计算最佳位置,避免超出视口边界
🎭 动画效果
- ✅ 手势动画:支持点击、滑动(上下左右四个方向)、脉冲等多种手势动画
- ✅ 平滑过渡:步骤切换时的流畅动画效果
- ✅ Canvas 2D:小程序端支持新版 Canvas 2D API,性能更优,自动降级兼容旧版
🔧 开发友好
- ✅ TypeScript:完整的类型定义支持,智能提示
- ✅ 零依赖:无需额外依赖,开箱即用
- ✅ 灵活配置:支持动态步骤、自定义内容、事件回调等
🚀 快速开始
第一步:引入组件
选项1:全局注册(推荐)
// main.js
import HyTour from '@/uni_modules/hy-interactive-tour/index.js'
Vue.use(HyTour)
选项2:页面内引入
<script>
import HyTour from '@/uni_modules/hy-interactive-tour/components/hy-interactive-tour/hy-tour.vue'
export default {
components: {
HyTour
}
}
</script>
第二步:定义引导步骤
data() {
return {
showTour: false,
tourSteps: [
{
selector: '#btn-new', // 目标元素的 ID 或 class
content: '点击这里创建新内容', // 提示文字
shape: 'round', // 高亮形状:round(圆角矩形) / rect(矩形) / circle(圆形)
position: 'bottom', // 提示框位置:bottom / top / left / right
padding: 10, // 高亮区域的内边距
showGesture: true, // 显示手势动画
gestureType: 'tap' // 手势类型:tap(点击) / swipe(滑动) / default(脉冲)
},
{
selector: '#btn-search',
content: '这里可以搜索内容',
shape: 'circle',
position: 'bottom'
}
]
}
}
第三步:在模板中使用
Vue 2 语法:
<template>
<view>
<!-- 你的页面内容 -->
<button id="btn-new">新建</button>
<button id="btn-search">搜索</button>
<!-- 引导组件(Vue 2 使用 .sync) -->
<hy-tour
:visible.sync="showTour"
:steps="tourSteps"
:mask-closable="true"
@finish="onTourFinish"
@skip="onTourSkip"
/>
</view>
</template>
Vue 3 语法:
<template>
<view>
<!-- 你的页面内容 -->
<button id="btn-new">新建</button>
<button id="btn-search">搜索</button>
<!-- 引导组件(Vue 3 使用 v-model:visible) -->
<hy-tour
v-model:visible="showTour"
:steps="tourSteps"
:mask-closable="true"
@finish="onTourFinish"
@skip="onTourSkip"
/>
</view>
</template>
第四步:触发引导
methods: {
// 在适当的时机开启引导
onReady() {
// 首次使用时显示引导
const hasShownTour = uni.getStorageSync('hasShownTour')
if (!hasShownTour) {
setTimeout(() => {
this.showTour = true
}, 500) // 延迟500ms,确保页面渲染完成
}
},
onTourFinish() {
console.log('引导完成')
uni.setStorageSync('hasShownTour', true)
uni.showToast({ title: '引导完成', icon: 'success' })
},
onTourSkip() {
console.log('用户跳过引导')
uni.setStorageSync('hasShownTour', true)
}
}
📚 API 文档
组件 Props
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| visible | Boolean | false |
否 | 是否显示引导(Vue 2 使用 :visible.sync,Vue 3 使用 v-model:visible) |
| steps | Array | [] |
是 | 引导步骤数组,详见下方 Steps 配置 |
| maskClosable | Boolean | false |
否 | 点击遮罩是否关闭引导 |
| autoStart | Boolean | true |
否 | visible 为 true 时是否自动开始引导 |
| zIndex | Number | 9999 |
否 | 组件层级,可根据实际情况调整 |
Steps 配置项
每个 step 对象支持以下属性:
| 属性 | 类型 | 默认值 | 必填 | 说明 |
|---|---|---|---|---|
| selector | String | - | 是 | 目标元素选择器,支持 ID(#id)或 class(.class) |
| content | String | - | 是 | 提示内容文本 |
| shape | String | 'rect' |
否 | 高亮形状: • rect - 矩形• circle - 圆形• round - 圆角矩形 |
| position | String | 'bottom' |
否 | 提示框位置: • top - 元素上方• bottom - 元素下方• left - 元素左侧• right - 元素右侧• auto - 自动计算最佳位置 |
| padding | Number | 8 |
否 | 高亮区域的内边距(单位:px) |
| showGesture | Boolean | false |
否 | 是否显示手势动画指示器 |
| gestureType | String | 'tap' |
否 | 手势类型(需要 showGesture=true):• tap - 点击手势,涟漪效果• swipe - 滑动手势,带方向箭头• default - 默认脉冲手势 |
| swipeDirection | String | 'right' |
否 | 滑动方向(仅 gestureType='swipe' 时有效):• left / right / up / down |
组件事件
| 事件名 | 说明 | 回调参数 | 触发时机 |
|---|---|---|---|
finish |
完成所有引导步骤 | - | 用户完成最后一步引导 |
skip |
用户跳过引导 | - | 用户点击"跳过"按钮 |
update:visible |
visible 状态更新 |
(visible: Boolean) |
visible 值变化时 |
💡 使用示例
示例 1:电商应用首页引导
<template>
<view>
<!-- 顶部搜索栏 -->
<view id="search-bar" class="search">
<input placeholder="搜索商品" />
</view>
<!-- 购物车按钮 -->
<view id="cart-btn" class="cart-icon">
🛒
</view>
<!-- 商品列表 -->
<view id="product-list" class="products">
<!-- 商品... -->
</view>
<!-- 引导组件 -->
<hy-tour
:visible.sync="showTour"
:steps="tourSteps"
@finish="onTourFinish"
/>
</view>
</template>
<script>
export default {
data() {
return {
showTour: false,
tourSteps: [
{
selector: '#search-bar',
content: '🔍 在这里搜索你想要的商品',
shape: 'round',
position: 'bottom',
padding: 12
},
{
selector: '#cart-btn',
content: '🛒 点击查看购物车',
shape: 'circle',
position: 'left',
showGesture: true,
gestureType: 'tap',
padding: 15
},
{
selector: '#product-list',
content: '👈 向左滑动查看更多商品',
shape: 'rect',
position: 'top',
showGesture: true,
gestureType: 'swipe',
swipeDirection: 'left'
}
]
}
},
onLoad() {
// 首次进入显示引导
const isFirstVisit = !uni.getStorageSync('visited_home')
if (isFirstVisit) {
setTimeout(() => {
this.showTour = true
}, 1000)
}
},
methods: {
onTourFinish() {
uni.setStorageSync('visited_home', true)
uni.showToast({ title: '欢迎使用!', icon: 'success' })
}
}
}
</script>
示例 2:社交应用功能引导
<template>
<view>
<view id="post-btn" class="post-button">+ 发布</view>
<view id="message-tab" class="tab">消息</view>
<view id="profile-tab" class="tab">我的</view>
<hy-tour
:visible.sync="showGuide"
:steps="guideSteps"
:mask-closable="true"
@finish="handleFinish"
@skip="handleSkip"
/>
</view>
</template>
<script>
export default {
data() {
return {
showGuide: false,
guideSteps: [
{
selector: '#post-btn',
content: '点击这里发布你的第一条动态吧!',
shape: 'round',
position: 'bottom',
showGesture: true,
gestureType: 'tap',
padding: 10
},
{
selector: '#message-tab',
content: '在这里查看好友消息',
shape: 'round',
position: 'top',
padding: 8
},
{
selector: '#profile-tab',
content: '个人资料和设置都在这里',
shape: 'round',
position: 'top',
padding: 8
}
]
}
},
methods: {
// 手动触发引导
startGuide() {
this.showGuide = true
},
handleFinish() {
console.log('用户完成引导')
// 记录用户已完成引导
this.markGuideAsCompleted()
},
handleSkip() {
console.log('用户跳过引导')
// 询问是否下次再显示
uni.showModal({
title: '提示',
content: '下次进入还要显示引导吗?',
success: (res) => {
if (!res.confirm) {
this.markGuideAsCompleted()
}
}
})
},
markGuideAsCompleted() {
uni.setStorageSync('guide_completed', true)
}
}
}
</script>
示例 3:动态生成引导步骤
export default {
data() {
return {
showTour: false,
tourSteps: [],
userPermissions: ['create', 'edit', 'export'] // 用户权限
}
},
onReady() {
// 根据用户权限动态生成引导步骤
this.tourSteps = this.generateTourSteps()
// 检查是否需要显示引导
if (this.shouldShowTour()) {
setTimeout(() => {
this.showTour = true
}, 800)
}
},
methods: {
generateTourSteps() {
const steps = []
// 基础步骤,所有用户都看到
steps.push({
selector: '#home-btn',
content: '这是首页,显示最新内容',
shape: 'round',
position: 'bottom'
})
// 根据权限添加步骤
if (this.userPermissions.includes('create')) {
steps.push({
selector: '#create-btn',
content: '点击这里创建新内容',
shape: 'round',
position: 'bottom',
showGesture: true,
gestureType: 'tap'
})
}
if (this.userPermissions.includes('export')) {
steps.push({
selector: '#export-btn',
content: '可以导出数据为 Excel',
shape: 'circle',
position: 'left'
})
}
return steps
},
shouldShowTour() {
// 版本更新后显示新功能引导
const lastVersion = uni.getStorageSync('last_version')
const currentVersion = '1.2.0'
if (lastVersion !== currentVersion) {
uni.setStorageSync('last_version', currentVersion)
return true
}
return false
}
}
}
🎨 高级用法
1. 自定义提示框内容
虽然组件暂不支持插槽,但你可以在 content 中使用富文本或 Emoji:
tourSteps: [
{
selector: '#feature1',
content: '✨ 这是新功能\n👉 点击体验',
shape: 'round',
position: 'bottom'
}
]
2. 分批次引导
对于复杂应用,可以分多个场景进行引导:
export default {
data() {
return {
showTour: false,
currentScene: 'home', // home, profile, settings
allSteps: {
home: [/* 首页引导步骤 */],
profile: [/* 个人中心引导步骤 */],
settings: [/* 设置页引导步骤 */]
}
}
},
computed: {
tourSteps() {
return this.allSteps[this.currentScene] || []
}
},
methods: {
startSceneGuide(scene) {
this.currentScene = scene
this.showTour = true
}
}
}
3. 版本更新引导
在版本更新后,只展示新功能引导:
methods: {
checkVersionUpdate() {
const lastVersion = uni.getStorageSync('app_version') || '1.0.0'
const currentVersion = '1.2.0'
if (this.compareVersion(lastVersion, currentVersion) < 0) {
// 显示新版本功能引导
this.showNewFeatureGuide()
uni.setStorageSync('app_version', currentVersion)
}
},
showNewFeatureGuide() {
this.tourSteps = [
{
selector: '#new-feature-1',
content: '🎉 新功能:支持批量导出',
shape: 'round',
position: 'bottom'
}
]
this.showTour = true
},
compareVersion(v1, v2) {
const arr1 = v1.split('.')
const arr2 = v2.split('.')
for (let i = 0; i < Math.max(arr1.length, arr2.length); i++) {
const num1 = parseInt(arr1[i]) || 0
const num2 = parseInt(arr2[i]) || 0
if (num1 !== num2) return num1 - num2
}
return 0
}
}
4. 带条件的步骤显示
根据用户状态或权限显示不同的引导:
computed: {
tourSteps() {
const steps = []
// 基础步骤(所有用户)
steps.push({
selector: '#btn-home',
content: '欢迎来到首页',
shape: 'round',
position: 'bottom'
})
// VIP 专属功能引导
if (this.userInfo.isVip) {
steps.push({
selector: '#vip-feature',
content: '🎖️ VIP 专享:高级功能',
shape: 'round',
position: 'bottom',
showGesture: true,
gestureType: 'tap'
})
}
// 管理员功能引导
if (this.userInfo.role === 'admin') {
steps.push({
selector: '#admin-panel',
content: '👑 管理员面板',
shape: 'rect',
position: 'left'
})
}
return steps
}
}
❓ 常见问题
Q1: 为什么引导没有显示?
A: 检查以下几点:
-
元素是否已渲染:确保目标元素已经渲染到页面上
onReady() { // ✅ 正确:在 onReady 后延迟启动 setTimeout(() => { this.showTour = true }, 500) } -
选择器是否正确:检查 ID 或 class 是否正确
// ❌ 错误 selector: 'btn-search' // ✅ 正确 selector: '#btn-search' // ID 选择器 selector: '.btn-search' // class 选择器 -
steps 数组是否为空:确保 steps 数组有内容
console.log('tourSteps:', this.tourSteps)
Q2: 小程序中提示框被遮挡怎么办?
A: 调整 zIndex 属性:
<hy-tour
:visible.sync="showTour"
:steps="tourSteps"
:z-index="10000"
/>
Q3: 如何在多个页面使用同一套引导?
A: 建议封装为 mixin 或 composition API:
// mixins/tourMixin.js
export default {
data() {
return {
showTour: false,
tourSteps: []
}
},
methods: {
initTour(steps) {
this.tourSteps = steps
const key = `tour_${this.$route.path}`
const hasShown = uni.getStorageSync(key)
if (!hasShown) {
setTimeout(() => {
this.showTour = true
}, 500)
}
},
onTourFinish() {
const key = `tour_${this.$route.path}`
uni.setStorageSync(key, true)
}
}
}
// 页面中使用
import tourMixin from '@/mixins/tourMixin'
export default {
mixins: [tourMixin],
onReady() {
this.initTour([
{ selector: '#btn1', content: '按钮1' },
{ selector: '#btn2', content: '按钮2' }
])
}
}
Q4: 如何让用户可以重新查看引导?
A: 提供一个"查看引导"的入口:
<template>
<view>
<!-- 设置页面的帮助按钮 -->
<button @click="showTourAgain">📖 查看功能引导</button>
<hy-tour
:visible.sync="showTour"
:steps="tourSteps"
@finish="onTourFinish"
/>
</view>
</template>
<script>
export default {
methods: {
showTourAgain() {
this.showTour = true
}
}
}
</script>
Q5: Vue 2 和 Vue 3 语法区别?
A:
<!-- Vue 2 项目使用 .sync 修饰符 -->
<hy-tour :visible.sync="showTour" :steps="tourSteps" />
<!-- Vue 3 项目使用 v-model: -->
<hy-tour v-model:visible="showTour" :steps="tourSteps" />
Q6: 在 nvue 页面中如何使用?
A: nvue 页面中选择器有所不同,需要注意:
- 只能使用
ref或id选择器 - 不支持 class 选择器
- 建议使用
id选择器
<!-- nvue 页面 -->
<template>
<view>
<view id="target-element">目标元素</view>
<hy-tour
:visible.sync="showTour"
:steps="[{ selector: '#target-element', content: '提示' }]"
/>
</view>
</template>
Q7: 如何自定义提示框样式?
A: 组件内部样式目前是固定的,如需深度定制,可以:
- 修改组件源码
hy-step.vue中的样式 - 或者提 Issue 反馈需求,后续版本会支持更多自定义选项
💪 最佳实践
1. 引导时机选择
// ✅ 推荐:首次使用时显示
onLoad() {
const isFirstTime = !uni.getStorageSync('has_used_app')
if (isFirstTime) {
this.showGuideOnReady = true
}
}
onReady() {
if (this.showGuideOnReady) {
setTimeout(() => {
this.showTour = true
}, 800) // 给页面渲染留足时间
}
}
// ❌ 不推荐:每次都显示,会让用户反感
onReady() {
this.showTour = true
}
2. 步骤数量控制
// ✅ 推荐:3-5 个步骤,重点突出
tourSteps: [
{ selector: '#key-feature-1', content: '核心功能1' },
{ selector: '#key-feature-2', content: '核心功能2' },
{ selector: '#key-feature-3', content: '核心功能3' }
]
// ❌ 不推荐:步骤过多,用户容易失去耐心
tourSteps: [
// 10+ 个步骤...
]
3. 文案编写建议
// ✅ 推荐:简洁明了,友好亲切
content: '👋 欢迎!点击这里开始创作'
// ❌ 不推荐:过于冗长或专业
content: '此按钮用于触发内容创建流程,点击后将进入编辑器界面,您可以在编辑器中...'
4. 善用手势动画
// ✅ 推荐:关键操作使用手势提示
{
selector: '#submit-btn',
content: '完成后点击提交',
showGesture: true,
gestureType: 'tap' // 点击手势
}
{
selector: '#slider',
content: '向左滑动查看更多',
showGesture: true,
gestureType: 'swipe',
swipeDirection: 'left' // 滑动手势
}
5. 记录用户行为
methods: {
onTourFinish() {
// 记录完成时间
uni.setStorageSync('tour_completed_time', Date.now())
// 上报统计
this.reportAnalytics('tour_completed', {
duration: this.tourDuration,
steps: this.tourSteps.length
})
},
onTourSkip() {
// 记录跳过行为
uni.setStorageSync('tour_skipped', true)
// 上报统计
this.reportAnalytics('tour_skipped', {
step_index: this.currentStepIndex
})
}
}
🔧 注意事项
1. 元素渲染时机
⚠️ 必须确保目标元素已渲染
// ✅ 正确做法
onReady() {
// 页面渲染完成后再启动
setTimeout(() => {
this.showTour = true
}, 500)
}
// ❌ 错误做法
onLoad() {
// 页面还没渲染完,元素可能不存在
this.showTour = true
}
2. 平台兼容性
| 平台 | 支持情况 | 注意事项 |
|---|---|---|
| H5 | ✅ 完全支持 | 使用 box-shadow 实现遮罩 |
| 微信小程序 | ✅ 完全支持 | 优先使用 Canvas 2D API |
| 支付宝小程序 | ✅ 完全支持 | 自动降级到旧版 Canvas |
| App (iOS/Android) | ✅ 完全支持 | 性能最佳 |
| uni-app x | ✅ 支持 | 需要 HBuilderX 3.6+ |
| nvue | ⚠️ 部分支持 | 只能使用 ID 选择器 |
3. 小程序限制
- 部分小程序平台不支持 Canvas 2D API,组件会自动降级
- 小程序中 Canvas 层级较高,确保
zIndex设置合理 - 自定义导航栏可能影响定位,需要调整 padding
4. 性能优化
// ✅ 推荐:按需加载
onReady() {
const needGuide = this.checkIfNeedGuide()
if (needGuide) {
// 只在需要时才渲染引导组件
this.showTour = true
}
}
// ❌ 不推荐:始终渲染引导组件
<hy-tour :visible.sync="showTour" :steps="tourSteps" />
5. 滚动容器
如果目标元素在自定义滚动容器(如 scroll-view)内:
<scroll-view scroll-y>
<view id="target">目标元素</view>
</scroll-view>
<!-- 自动滚动功能可能无效,需要手动处理 -->
6. 动态内容
对于动态加载的内容,确保内容加载完成后再启动引导:
async onReady() {
// 等待数据加载
await this.loadData()
// 等待列表渲染
await this.$nextTick()
// 再启动引导
setTimeout(() => {
this.showTour = true
}, 500)
}
祝你的应用引导体验越来越好! 🎉

收藏人数:
下载插件并导入HBuilderX
赞赏(0)
下载 41
赞赏 0
下载 11094460
赞赏 1804
赞赏
京公网安备:11010802035340号