遇到的問題
網(wǎng)上的一些資料都是介紹怎么使用vue-tour的,今天分享一個(gè)特殊場景下的導(dǎo)航,
我使用的是v3-tour,使用方式
npm i v3-tour
- 首先是導(dǎo)航頁面不在同一個(gè)頁面,需要頁面跳轉(zhuǎn)后繼續(xù)進(jìn)行導(dǎo)航
- 跳到到第二個(gè)頁面后,需要和上一步的導(dǎo)航進(jìn)行關(guān)聯(lián),即跳轉(zhuǎn)到第二頁后“第二步導(dǎo)航”需要展示“上一步”按鈕
- 進(jìn)入第二頁導(dǎo)航后不能從第一步重頭開始,要從第二步開始
跳轉(zhuǎn)頁面分布如下所示:
[圖片上傳失敗...(image-76ed25-1724568888820)]
基礎(chǔ)使用方式
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;
// 我的應(yīng)用因?yàn)樾枰诱谡謱铀垣@取到目標(biāo)元素位置,根據(jù)目標(biāo)位置設(shè)置彈出層中元素的位置
if (currentStep === 0) {
//獲取目標(biāo)位置
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 () {
//關(guān)閉遮罩層關(guān)閉提示
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(()=>{
// 初始化導(dǎo)航
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>
思考:如果想在第二個(gè)頁面時(shí)保留上一步操作按鈕,steps配置必須把這些步驟當(dāng)做分布在一個(gè)頁面進(jìn)行配置,因此每個(gè)頁面steps配置必須是全的。
實(shí)踐:通過實(shí)踐發(fā)現(xiàn)如果steps配置第一個(gè)元素的target在當(dāng)前頁面找不到的話,就不會(huì)彈出步驟提示框,因此每個(gè)頁面steps中配置的目標(biāo)元素也必須存在。
Q:怎么在跳轉(zhuǎn)一下步時(shí)自動(dòng)導(dǎo)航到下一個(gè)頁面呢?
A:通過路由切換實(shí)現(xiàn)。
Q:路由切換后,會(huì)從第一步開始彈出,怎么讓步驟從第二步彈出?
A:找到當(dāng)前導(dǎo)航組件實(shí)例后,通過編程方式操作下一步$tours['myTour1'].nextStep
第一個(gè)頁面步驟跳轉(zhuǎn)處理邏輯,在callback回調(diào)函數(shù)onNextStep函數(shù)中處理跳轉(zhuǎn)即點(diǎn)擊下一步時(shí)進(jìn)行路由切換
let myCallbacks = ref({
onNextStep(currentStep: number) {
// 路由跳轉(zhuǎn)處理邏輯
navToSetPrompt()
},
onStop() {
//關(guān)閉遮罩層關(guān)閉提示
showOverlay.value = false
}
})
第二個(gè)頁面處理初始化步驟。進(jìn)入第二個(gè)頁面應(yīng)該從step2開始,但是如果該頁面不存在step1的目標(biāo)元素則會(huì)阻斷頁面不會(huì)彈出來步驟提示框,因此第二個(gè)頁面需要包含第一個(gè)頁面的target元素,并且在初始化完成后自動(dòng)跳過第一步。
let myCallbacks = ref({
onStart() {
nextTick(() => {
const $tours = insternalInstance.appContext.config.globalProperties.$tours
if ($tours) {
if ($tours['myTour1']) {
// 跳過第一步
$tours['myTour1'].nextStep()
// 從第三個(gè)頁面返回后應(yīng)該跳轉(zhuǎn)至第四步,在此做判斷,根據(jù)頁面路由攜帶參數(shù)進(jìn)行區(qū)分
if (queryParams?.from === 'abnormal') {
// 跳過第二步驟
$tours['myTour1'].nextStep()
activeStep.value = 2
} else {
activeStep.value = 1
}
}
}
})
},
onNextStep(currentStep: number) {
// 點(diǎn)擊第三步時(shí)處理內(nèi)容
if (activeStep.value === 2) {
navToSetting(1)
}
activeStep.value++
console.log('下一步-prompt', currentStep)
},
onStop() {
//關(guān)閉遮罩層關(guān)閉提示
showOverlay.value = false
},
onPreviousStep(currentStep: number) {
// 當(dāng)前元素在第一步時(shí)應(yīng)該返回到首頁
activeStep.value--
if (activeStep.value === 0) {
showOverlay.value = false
// 點(diǎn)擊上一步切換到首頁
navToHome()
}
console.log('上一步-prompt', currentStep)
}
})
第二個(gè)頁面跳轉(zhuǎn)第三個(gè)頁面處理方式類似上面的。
通過以上操作現(xiàn)在的情況是,可以不同頁面之間的跳轉(zhuǎn)了也能自動(dòng)定位到步驟了,但是頁面切換過程中會(huì)上一步的步驟會(huì)有一個(gè)閃爍的過程
使用絕對定位將目標(biāo)元素設(shè)置在頁面可視區(qū)域之外,這樣切換上一步和下一步的時(shí)候不在該頁面的導(dǎo)航就不會(huì)出現(xiàn)在該頁面了,又能保證目標(biāo)元素在該頁面可以被查找到。