遇到的问题
网上的一些资料都是介绍怎么使用vue-tour的,今天分享一个特殊场景下的导航,
我使用的是v3-tour
,使用方式
npm i v3-tour
- 首先是导航页面不在同一个页面,需要页面跳转后继续进行导航
- 跳到到第二个页面后,需要和上一步的导航进行关联,即跳转到第二页后“第二步导航”需要展示“上一步”按钮
- 进入第二页导航后不能从第一步重头开始,要从第二步开始
跳转页面分布如下所示:
[图片上传失败...(image-76ed25-1724568888820)]
基础使用方式
import { onMounted, ref } from "vue"
let steps = ref([
{
target: "#goods-tour",
content: `<div class="demoss"> <div class="tour-title">步骤一</div><div class="tour-content">步骤一</div></div>`,
params: {
placement: "bottom",
},
},
{
target: "#quote-mode-tour",
content: `<div class="demoss"> <div class="tour-title">步骤二</div><div class="tour-content">步骤二</div></div>`,
params: {
placement: "bottom",
},
},
{
target: "#desnation-mode-tour",
content: `<div class="demoss"> <div class="tour-title">步骤三</div><div class="tour-content">步骤三</div></div>`,
params: {
placement: "bottom",
},
},
{
target: "#profit-mode-tour",
content: `<div class="demoss"> <div class="tour-title">步骤四</div><div class="tour-content">步骤四</div></div>`,
params: {
placement: "bottom",
},
},
]);
// 配置labels,自定义按钮文案
let labels = {
// buttonSkip: 'Skip tour',
// buttonPrevious: '上一步',
buttonNext: "下一步",
buttonStop: "我知道了",
};
let options = ref({
useKeyboardNavigation: false,
labels: labels,
});
let myCallbacks = ref({
onNextStep(currentStep: number) {
activeStep.value = currentStep + 1;
// 我的应用因为需要加遮罩层所以获取到目标元素位置,根据目标位置设置弹出层中元素的位置
if (currentStep === 0) {
//获取目标位置
let goodsTourTop: number =
document.querySelector("#quote-mode-tour").offsetTop;
cellTop.value = goodsTourTop;
}
if (currentStep === 1) {
let goodsTourTop: number = document.querySelector(
"#desnation-mode-tour"
).offsetTop;
cellTop.value = goodsTourTop;
}
if (currentStep === 2) {
let goodsTourTop: number =
document.querySelector("#profit-mode-tour").offsetTop;
cellTop.value = goodsTourTop;
}
},
onStop: async function () {
//关闭遮罩层关闭提示
showOverlay.value = false;
},
});
const initStep = function () {
setTimeout(() => {
const $tours = insternalInstance.appContext.config.globalProperties.$tours;
if ($tours) {
if ($tours["myTour"]) {
showOverlay.value = true;
$tours["myTour"].start();
}
}
}, 100);
};
onMounted(()=>{
// 初始化导航
initStep();
})
页面部分
<mz-overlay :show="showOverlay" lock-scroll>
<div v-if="activeStep === 0" :style="{ top: cellTop + 'px', position: 'absolute' }">步骤一</div>
<div v-if="activeStep === 1" :style="{ top: cellTop + 'px', position: 'absolute' }">步骤二</div>
<div v-if="activeStep === 2" :style="{ top: cellTop + 'px', position: 'absolute' }">步骤三</div>
<div v-if="activeStep === 3" :style="{ top: cellTop + 'px', position: 'absolute' }">步骤四</div>
</mz-overlay>
<v-tour name="myTour" :style="{ zIndex: showOverlay ? 99 : -1 }" :steps="steps" :options="options" :callbacks="myCallbacks"></v-tour>
思考:如果想在第二个页面时保留上一步操作按钮,steps
配置必须把这些步骤当做分布在一个页面进行配置,因此每个页面steps
配置必须是全的。
实践:通过实践发现如果steps
配置第一个元素的target
在当前页面找不到的话,就不会弹出步骤提示框,因此每个页面steps
中配置的目标元素也必须存在。
Q:怎么在跳转一下步时自动导航到下一个页面呢?
A:通过路由切换实现。
Q:路由切换后,会从第一步开始弹出,怎么让步骤从第二步弹出?
A:找到当前导航组件实例后,通过编程方式操作下一步$tours['myTour1'].nextStep
第一个页面步骤跳转处理逻辑,在callback
回调函数onNextStep
函数中处理跳转即点击下一步时进行路由切换
let myCallbacks = ref({
onNextStep(currentStep: number) {
// 路由跳转处理逻辑
navToSetPrompt()
},
onStop() {
//关闭遮罩层关闭提示
showOverlay.value = false
}
})
第二个页面处理初始化步骤。进入第二个页面应该从step2
开始,但是如果该页面不存在step1
的目标元素则会阻断页面不会弹出来步骤提示框,因此第二个页面需要包含第一个页面的target
元素,并且在初始化完成后自动跳过第一步。
let myCallbacks = ref({
onStart() {
nextTick(() => {
const $tours = insternalInstance.appContext.config.globalProperties.$tours
if ($tours) {
if ($tours['myTour1']) {
// 跳过第一步
$tours['myTour1'].nextStep()
// 从第三个页面返回后应该跳转至第四步,在此做判断,根据页面路由携带参数进行区分
if (queryParams?.from === 'abnormal') {
// 跳过第二步骤
$tours['myTour1'].nextStep()
activeStep.value = 2
} else {
activeStep.value = 1
}
}
}
})
},
onNextStep(currentStep: number) {
// 点击第三步时处理内容
if (activeStep.value === 2) {
navToSetting(1)
}
activeStep.value++
console.log('下一步-prompt', currentStep)
},
onStop() {
//关闭遮罩层关闭提示
showOverlay.value = false
},
onPreviousStep(currentStep: number) {
// 当前元素在第一步时应该返回到首页
activeStep.value--
if (activeStep.value === 0) {
showOverlay.value = false
// 点击上一步切换到首页
navToHome()
}
console.log('上一步-prompt', currentStep)
}
})
第二个页面跳转第三个页面处理方式类似上面的。
通过以上操作现在的情况是,可以不同页面之间的跳转了也能自动定位到步骤了,但是页面切换过程中会上一步的步骤会有一个闪烁的过程
使用绝对定位将目标元素设置在页面可视区域之外,这样切换上一步和下一步的时候不在该页面的导航就不会出现在该页面了,又能保证目标元素在该页面可以被查找到。