Code前端首页关于Code前端联系我们

在 vue 项目中跨页面(交叉路由)使用 Intro.js

terry 2年前 (2023-09-08) 阅读数 145 #Vue
入门指南工具

功能要求

公司要求初步指导要在自己的平台上实施,并且应该是跨页面、跨方向的。我在网上搜索了初学者指南插件,最终找到了 Intro.js。

我写的大部分内容都是一个想法。如果你理解了它,你就可以轻松实现这些效果。如果直接粘贴的话,估计会很别扭。

建议您访问Intro.js官网看一下demo,理解它,然后根据demo看看它是如何工作的。

我只是一个小草根程序员。如果你有一个让我发笑的想法或逻辑,请不要嘲笑我。请告诉我,非常感谢。

以下是我遇到并试图解决的真实问题。如果有更好的解决方案,可以留言讨论。

使用Intro.js时的问题和代码

1。无法穿越路线

最大的问题是Intro.js无法遍历路由,因为它是根据当前页面的dom的唯一Id来获取并渲染启动指南的,因此无法获取不渲染的页面。
所以我想从头开始在每个页面上加载Intro.js。启动上一个页面后,直接router.push跳转到下一个路由,然后自动加载启动,然后按下一个路由,ok,完美的俄罗斯套娃

首先,我们在utils.js文件中嵌入了一个Intro.js工具类,以便更容易地直接链接各个页面。我将在这里发布代码的最终版本,我认为它相对容易理解。

utils -> intro.js

import introJs from 'intro.js'
import 'intro.js/introjs.css';
import router from '@/router'
import store from '@/store'
let count = 0 // 初始化为0,后面会根据每一步传入的dom的id选择器 判断当前在第几步
let state = 0 // skip: 0 ,done: 1;
export function guide (introSteps) {
// console.log(sessionStorage.getItem('isIntro'))
if (!parseInt(sessionStorage.getItem('isIntro'))) {
return
}
introJs().setOptions({
steps: introSteps,
/* 当位置选择自动的时候,位置排列的优先级 */
positionPrecedence: ["top", "bottom", "right", "left"],
prevLabel: "上一步",
nextLabel: "下一步",
skipLabel: "跳过",
// 这里因为每个页面的最后一步其实就会显示doneLabel了,而实际上我们的新手引导操作并没有完成,需要跳转路由继续,所以显示的是下一步而非完成。
doneLabel: "下一步", 
hidePrev: true,
exitOnOverlayClick: false,
/* 是否显示说明的数据步骤*/
showStepNumbers: false,
/* 是否使用点点点显示进度 */
showBullets: false,
/* 是否使用键盘Esc退出 */
exitOnEsc: false,
/* 默认提示位置 */
hintPosition: 'top-left',
/* 说明高亮区域的样式 */
highlightClass: 'customHighlight',
/* 引导说明文本框的样式 */
tooltipClass: 'customTooltip'
}).onchange(function (targetElement) {
// 每次change时触发,我的id样式是“guide-step<id>”
// id代表新手引导的第几步,例如“guide-step1”,通过id判断当前是第几步
count = parseInt(targetElement.id.slice(-1))
}).onafterchange(function (targetElement) {
// 公司设计的新手引导只有七步,如果count == 7了,说明现在是最后一步
// 跳转完成后用js的dom操作将doneLabel由“下一步”改为“完成”
if (count === 7) {
let i = document.getElementsByClassName('introjs-donebutton')[0].innerHTML = '知道了'
}
}).oncomplete(function (targetElement) {
// 点击完成以及跳过按钮后执行的事件,不区分完成和跳过。
state = 1
setTimeout(() => {
if (state) {
judgeCount()
}
}, 200)
}).onexit(function (targetElement) {
// 点击完成按钮后, 执行的事件
}).onskip(function (targetElement) {
// 点击跳过按钮后, 执行的事件
// onskip这个我当时在官网api里查不到,是我自己翻源码翻出来的,折腾半天,无语。
// 因为点击跳过以后是默认完成了新手引导,此时就需要将状态传给后端,保证下一次进入有Intro.js的页面时时不加载新手引导了。
// 因为vue是跨路由写的,每个页面的完成其实都不是用户真正完成了新手引导
// 所以如果不区分完成和跳过各自触发的事件的话,我们就不会知道用户当前是跳过( ==完成了新手引导)还是只是当前页面的完成,需要继续跳转下一个路由。
state = 0
// 存储进缓存,下次进入新手引导路由页时将不在触发Intro.js
store.state.introStepInfo.isIntro = state
sessionStorage.setItem('isIntro', state)
}).start();
}
// 这个是每一步新手引导对应的点击下一步时对应应该进行的操作
// 我这边,1,2步在一个页面,3,4步在一个页面,5,6步在一个页面,第7步在一个页面
// 所以1,3,5的时候我不需要进行特定操作,按照Intro.js走就行了
function judgeCount () {
// 这是事先预存的跳转路由需要的一些数据
let _introStepInfo = JSON.parse(sessionStorage.getItem('introStepInfo'))
switch (count) {
case 1:
break
case 2:
router.push({
path: '/courseDetail',
query: {
id: _introStepInfo.courseId
}
})
break
case 3:
break
case 4:
let _introChapterName = sessionStorage.getItem('chapterName')
router.push({
path: '/coursePreview',
query: {
id: _introStepInfo.courseId,
chapterId: _introStepInfo.chapterId
}
})
break
case 5:
break
case 6:
router.push({
path: '/myCourses'
})
break
case 7:
sessionStorage.setItem('isIntro', 0)
break
}
}

2。获取并显示页面导航要显示的所有数据后加载 Intro.js 文件

需要注意的是,从后端接收到数据后,需要渲染一些DOM。如果不显示,Intro.js无法获取唯一ID值。

所以在axios包中我们需要全局设置一个isAxios布尔变量为false,并在请求返回后将其更改为true。
这只是最基本的。您还应该考虑页面是否有两个以上需要数据收集才能呈现的 DOM。因此,目前您需要添加另一个全局变量 count,根据请求+1。如果答案是-1,如果数字是0,则将isAxios设置为true。然后我们在页面的生命周期mounted()中设置一个500毫秒的计时器,它应该渲染Intro.js并判断isAxios。如果这是真的,那么我们可以开始入门指南并在完成后清除。

这些还不成熟。如果有更好的方法,也可以提出来。

使用 intro.js 设备类

// 引入自己封装的新手引导函数
import { guide } from '@/utils/intro'

在mounted()生命周期中设置定时器

let i = setInterval(() => {
if (!this.isAxios) {
guide([
{
title: '开放课程',
intro: '查看您已采购的全部课程。(1/7)',
element: document.querySelector('#guide-step1')
},
{
title: '课程资源',
intro: '点击任意一门课程封面进入该课程。(2/7)',
element: document.querySelector('#guide-step2')
}
])
clearInterval(i)
}
}, 500)

嵌入轴子的时候其实还有很多小细节需要注意,但是和intro.js关系不大,所以这次就不介绍了。只要多关注他们就可以了。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门