|
新手引导一般用于新用户打开APP,引导用户使用的流程
实现思路,以uni-app为例,也是基于vue实现
1. 获取需要高亮元素的宽高以及left, top 使用 boundingClientRect 方法
2. 使用box-shadow 将其它区域遮盖住即可
具体步骤:
一、封装我们需要的数据
data () {
return {
guideList: [{
el: '.head-portrait .avge', // 需要高亮的元素,这里最好唯一
tips: '点击这里,加入神奇的左汪右喵世界', // 提示文字
next: '下一步', // 下一步按钮显示文字
style: { // 高亮样式
borderRadius: '12rpx',
margin: '-10rpx 0 0 -10rpx'
},
tipStyle: { // tips样式
left: '-200rpx'
}
}, {
el: '.navList .nav-image-1-1',
tips: '点击这里,快速记录小可爱成长的点点滴滴',
next: '下一步',
style: {
borderRadius: '12rpx',
margin: '-10rpx 0 0 -32rpx'
},
tipStyle: {
left: '-164rpx'
}
}, {
el: '.navList .nav-image-2-3',
tips: '点击这里,是小可爱的智能硬件仓库',
next: '下一步',
style: {
borderRadius: '12rpx',
margin: '-10rpx 0 0 -32rpx'
},
tipStyle: {
left: '-356rpx'
}
}],
index: 0, // 当前展示的索引
showGuide: true, // 是否显示引导
}
},
二、 展示布局
<view class="guide" @touchmove.stop.prevent="moveHandle" v-if="showGuide">
<view
:style="getStyle"
class="guide-box"
catchtouchmove="true">
<view class="tips" :style="{left: guideInfo.tipStyle.left}">
<view class="text">{{ guideInfo.tips }}</view>
<view class="next">
<text @click="next">{{ guideInfo.next }}</text>
</view>
</view>
<view class="arrow"></view>
</view>
</view>
三、计算当前展示的数据
computed: {
guideInfo() {
return this.guideList[this.index];
},
getStyle () {
const { width, height, left, top, style } = this.guideInfo;
return {
width: 120 + 'rpx',
height: 120 + 'rpx',
left: left + 'px',
top: top + 'px',
...style,
boxShadow: 'rgb(33 33 33 / 80%) 0px 0px 0px 0px, rgb(33 33 33 / 50%) 0px 0px 0px 5000px'
}
}
},
四、方法处理
mounted() {
const guide = uni.getStorageSync('guide_key');
if (!guide) {
this.getDomInfo();
} else {
this.showGuide = false;
}
},
methods: {
getDomInfo () {
const { el } = this.guideInfo;
const query = uni.createSelectorQuery().in(this.$root);
setTimeout(() => {
query.select(el).boundingClientRect(data => {
if (data) {
const index = this.index;
this.guideList.splice(index, 1, {
...this.guideList[index],
left: data.left,
top: data.top,
width: data.width,
height: data.height
});
}
}).exec();
}, 10)
},
next () {
if (this.index === this.guideList.length - 1) {
this.showGuide = false;
uni.setStorageSync('guide_key', 'true');
} else {
this.index += 1;
this.getDomInfo();
}
},
moveHandle () {
return false;
}
},
五、样式展示
<style lang="less" scoped>
.guide {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0px;
z-index: 1000;
.guide-box {
position: fixed;
z-index: 100;
transition: all 0.2s;
&::before {
content: '';
height: 140rpx;
width: 140rpx;
border: 1px dashed #fff;
border-radius: 12rpx;
position: absolute;
top: -12rpx;
left: -12rpx;
}
.arrow {
height: 20rpx;
width: 20rpx;
background: #DC5F45;
position: absolute;
top: 144rpx;
left: 50%;
transform: rotate(45deg);
}
.tips {
background: #DC5F45;
box-shadow: 0px 2px 9px 0px rgba(0, 0, 0, 0.1);
color: #fff;
position: absolute;
top: 152rpx;
left: -50%;
padding: 15rpx 20rpx;
font-size: 28rpx;
border-radius: 12rpx;
.text {
white-space: nowrap;
}
.next {
text-align: right;
padding-right: 0rpx;
margin-top: 10rpx;
}
}
}
}
</style>
参考网站: https://introjs.com/docs/examples/basic/json-config
来源:https://www.cnblogs.com/shenjp/p/14873233.html |