先上需求图
这里提供两种方法:
第一种,直接用图片,虽然low了点,但是快。
第二种,就是使用定位,找到对应的dom,然后再进行解释;思路来自插件市场,但这边已经进行了加功,升级。下面进入代码:
<!-- guide.vue -->
<template>
<view v-show="show" class="main" @touchmove.stop>
<view class="rect-shadow" :style="{'width':width+'px','height':height+'px','left':left+'px',top:top+'px','border-radius': noticeArray[currentIndex].radius?noticeArray[currentIndex].radius+'rpx':'' }"></view>
<template v-if="noticeArray[currentIndex].type == 'left' ">
<view class="show-message_left" :style="{'top': top +'px', 'right': winWidth-right+width+20+'px' }">
<view style="padding: 12rpx 18rpx;">{{showMessage}}</view>
</view>
</template>
<template v-if="noticeArray[currentIndex].type == 'top' ">
<view :class="left<(winWidth/2)?'show-message_top_left':'show-message_top_right'" :style="{'top': (top-height-topMsgHeght) +'px', 'left': left<(winWidth/2)?left+'px':'' , 'right': left>(winWidth/2)?(winWidth-right)+'px':'' }">
<view style="padding: 12rpx 18rpx;">{{showMessage}}</view>
</view>
</template>
<template v-if="noticeArray[currentIndex].type == 'right' ">
<view class="show-message_right" :style="{'top': top +'px', 'left': (left+width+20) +'px' }">
<view style="padding: 12rpx 18rpx;">{{showMessage}}</view>
</view>
</template>
<template v-if="noticeArray[currentIndex].type == 'bottom' ">
<view :class="left<(winWidth/2)?'show-message_bottom_left':'show-message_bottom_right'" :style="{'top': (top+height+15) +'px', 'left': left<(winWidth/2)?left+'px':'' , 'right': left>(winWidth/2)?(winWidth-right) +'px':'' }">
<view style="padding: 12rpx 18rpx;">{{showMessage}}</view>
</view>
</template>
<view class="cover-wrap" >
<view class="guide-next" @tap="click" :style="{color: currentIndex==noticeArray.length-1? '#EA3E4F':'#000000'}">{{nextText}}</view>
</view>
</view>
</template>
<script>
export default {
name: "guide",
props: {
show: {
type: Boolean,
default: false
},
left: {
type: [Number, String],
default: ''
},
right: {
type: [Number, String],
default: ''
},
top: {
type: [Number, String],
default: ''
},
width: {
type: [Number, String],
default: ''
},
height: {
type: [Number, String],
default: ''
},
showMessage: {
type: String,
default: ''
},
currentIndex: {
type: Number,
default: 0
},
noticeArray: {
type: Array,
default: []
}
},
data() {
return {
topMsgHeght: 0,
winWidth: 0,
nextText: '下一步' // 知道了,关闭说明
}
},
watch: {
show(n) {},
currentIndex(value) {
if (value != this.noticeArray.length&&this.noticeArray[value].type == 'top') {
const className = this.left<(this.winWidth/2) ? '.show-message_top_left' : '.show-message_top_right'
const query = uni.createSelectorQuery().in(this);
query.select(className).boundingClientRect(data => {
// 29px 为一行语句的高度
this.topMsgHeght = data.height - 29
}).exec();
}
if (value == this.noticeArray.length-1) {
this.nextText = '知道了,关闭说明'
}
}
},
methods: {
click() {
this.$emit('click');
},
// 清除页面所有定时器
clearTimeAll(){
clearTimeout(this.stt01);
}
},
created() {
this.stt01 = setTimeout(() => {
uni.getSystemInfo({
success: (res) => {
this.winWidth = res.windowWidth;
}
});
}, 60)
}
}
</script>
<style lang="scss">
.main {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99999;
}
.rect-shadow {
position: absolute;
border-radius: 12px;
box-shadow: 0 0 0 3000px rgba(0, 0, 0, 0.5);
pointer-events: none;
}
.show-message_left,
.show-message_top_left,
.show-message_top_right,
.show-message_right,
.show-message_bottom_left,
.show-message_bottom_right {
position: absolute;
border-radius: 12rpx;
background-color: rgba(0,0,0,.5);
text-align: center;
pointer-events: none;
color: #fff;
font-size: 24rpx;
max-width: 50%;
text-align: left;
}
.show-message_left::after {
content: '';
border-left: 12rpx solid rgba(0,0,0,.5);
border-top: 12rpx solid transparent;
border-right: 12rpx solid transparent;
border-bottom: 12rpx solid transparent;
width: 0;
height: 0;
position: absolute;
top: 25%;
right: -22rpx;
}
.show-message_top_left::after,.show-message_top_right::after {
content: '';
border-left: 12rpx solid transparent;
border-top: 12rpx solid rgba(0,0,0,.5);
border-right: 12rpx solid transparent;
border-bottom: 12rpx solid transparent;
width: 0;
height: 0;
position: absolute;
top: 100%;
}
.show-message_top_left::after {
left: 20%;
}
.show-message_top_right::after {
right: 20%;
}
.show-message_right::after {
content: '';
border-left: 12rpx solid transparent;
border-top: 12rpx solid transparent;
border-right: 12rpx solid rgba(0,0,0,.5);
border-bottom: 12rpx solid transparent;
width: 0;
height: 0;
position: absolute;
top: 25%;
left: -24rpx;
}
.show-message_bottom_left::after, .show-message_bottom_right::after {
content: '';
border-left: 12rpx solid transparent;
border-top: 12rpx solid transparent;
border-right: 12rpx solid transparent;
border-bottom: 12rpx solid rgba(0,0,0,.5);
width: 0;
height: 0;
position: absolute;
top: -22rpx;
}
.show-message_bottom_left::after {
left: 20%;
}
.show-message_bottom_right::after {
right: 20%;
}
.cover-wrap {
width: 100vw;
height: 100vh;
top: 0;
left: 0;
position: absolute;
.guide-next {
// padding: 0 40rpx;
padding: 16rpx 32rpx;
height: 72rpx;
background-color: #FFFFFF;
text-align: center;
font-size: 28rpx;
border-radius: 38rpx;
position: absolute;
bottom: 372rpx;
left: 50%;
transform: translate(-50%,0);
}
}
</style>
下面就是使用的方法
<template>
<view class="content">
<image class="logo" src="/static/logo.png" id="testid1"></image>
<view class="text-area" id="testid2">
<text class="title">Hello</text>
</view>
<view id="testid3">测试行1</view>
<view id="testid4"><button >测试按钮1</button></view>
<!-- 新手引导 -->
<guide :show="showGuide" :width="cWidth" :height="cHeight" :left="cLeft" :right="cRight" :top="cTop" :showMessage='cShowMsg' :currentIndex="currentIndex" :noticeArray="noticeArray" @click="clicktoNext"></guide>
</template>
<script>
import guide from '@/components/guide/guide.vue'
export default {
data() {
return {
showGuide: true, //引导是否显示
cShowMsg: '', // 展示的解释语
cWidth: '',
cHeight: '',
cLeft: '',
cTop: '',
currentIndex: 0,
//配置需要显示引导的view以及引导显示的msg
noticeArray: [{
"showID": "testid1", // 对应的id
"showMessage": "测试文本1", // 对应的解释文本
"type": "left" // 解释框的气泡类型
},
{
"showID": "testid2",
"showMessage": "测试文本2",
"type": "right"
},
{
"showID": "testid3",
"showMessage": "测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本测试多行文本",
"type": "top"
},
{
"showID": "testid4",
"showMessage": "测试文本4",
"type": "bottom"
}
]
}
},
components: {
guide
},
onLoad() {
let _this = this;
this.$nextTick(function() {
if (_this.currentIndex >= _this.noticeArray.length) {
_this.showGuide = false;
return;
}
_this.showGuide = true;
_this.cShowMsg = _this.noticeArray[_this.currentIndex].showMessage;
var idS = '#' + _this.noticeArray[_this.currentIndex].showID;
console.log(idS)
//根据布局信息显示引导框位置
const query = uni.createSelectorQuery().in(_this);
query.select(idS).boundingClientRect(data => {
console.log("得到布局位置信息" + JSON.stringify(data));
_this.cWidth = data.width;
_this.cHeight = data.height;
_this.cLeft = data.left;
_this.cTop = data.top;
}).exec();
});
},
methods: {
clicktoNext() {
console.log('点击了下一个')
if (this.currentIndex >= this.noticeArray.length) {
this.showGuide = false;
return;
}
this.noticeArray[this.currentIndex].zindex = 0;
this.cShowMsg = '';
this.currentIndex++;
if (this.currentIndex >= this.noticeArray.length) {
this.showGuide = false;
return;
}
this.cShowMsg = this.noticeArray[this.currentIndex].showMessage;
var idS = '#' + this.noticeArray[this.currentIndex].showID;
console.log(idS)
const query = uni.createSelectorQuery().in(this);
query.select(idS).boundingClientRect(data => {
console.log("得到布局位置信息" + JSON.stringify(data));
this.cWidth = data.width;
this.cHeight = data.height;
this.cLeft = data.left;
this.cTop = data.top;
}).exec();
},
}
}
</script>
以上就是新手引导功能代码,直接复制粘贴,便可以体验,如果对你有帮助,不要忘记点赞、评论加关注哦~~