qiankun微服务使用intro.js总结

前言


最近在使用qiankun微服务架构,有个须要给系统加引导的需求,而后就决定使用intro.js。也是看了掘金的一位博主的帖子(连接以下)。

juejin.cn/post/696464…css


可是我要讲的内容有,如何在微服务中进行主模块和子模块的完美引导样式修改,以及踩的一些坑。vue

再附上一个官网的连接 introjs.com/typescript

注意

intro截图.png 这个插件是GNU AGPLv3 也就是说若是你商用那是要公开源码的,或者你得买他的版权(网上查的不知道对不对) 反正我是花钱买了受权9.99刀,固然当时为了想省这六十几块人民币也试过同类型的插件driver.js可是区别仍是蛮大的。ps:别问我怎么知道的由于我用两个插件都写了一遍。 这里在多说一点把若是你是小项目,且要求不是很高,功能不是不少,能够选择Dirver。毕竟他开源免费。固然你要是以为这个点钱不算什么别犹豫直接intro.js。缓存


基本用法

先说使用这个基本和上面的博主相同当时也发现了一些更好的使用技巧。这是封装的代码。下面具体细节一一讲解。markdown

import introJs from 'intro.js'
import 'intro.js/introjs.css'
// import router from '@/router'
import Vuex from '@/store'
let count = 0 // 初始化为0,后面会根据每一步传入的dom的id选择器 判断当前在第几步
// let state = 0 // skip: 0 ,done: 1;
export function guide(introSteps: Array<any>) {
  let isSkip: boolean = false
  const sesionData = JSON.parse(localStorage.getItem('isIntro') || 'null')
  if (localStorage.getItem('isIntro') && sesionData.state === 0) {
    return
  }

  introJs()
    .setOptions({
      steps: introSteps,
      /* 当位置选择自动的时候,位置排列的优先级 */
      positionPrecedence: ['right', 'top', 'bottom', 'left'],
      prevLabel: '上一步',
      nextLabel: '下一步',
      skipLabel: '<div/>',
      // 这里由于每一个页面的最后一步其实就会显示doneLabel了,而实际上咱们的新手引导操做并无完成,须要跳转路由继续,因此显示的是下一步而非完成。
      doneLabel: '下一步',
      hidePrev: true,
      exitOnOverlayClick: false,
      /* 是否显示说明的数据步骤*/
      showStepNumbers: false,
      /* 是否使用点点点显示进度 */
      showBullets: false,
      /* 是否使用键盘Esc退出 */
      exitOnEsc: false,
      /* 默认提示位置 */
      hintPosition: 'top-right',
      /* 说明高亮区域的样式 */
      highlightClass: 'customHighlight',
      /* 引导说明文本框的样式 */
      tooltipClass: 'customTooltip',
    })
    .onchange(function (targetElement: any) {
      // 每次change时触发,个人id样式是“guide-step<id>”
      // id表明新手引导的第几步,例如“guide-step1”,经过id判断当前是第几步
      count = parseInt(targetElement.id.slice(-1))
    })
    .onafterchange(function (targetElement: any) {
      // 跳转完成后用js的dom操做将doneLabel由“下一步”改成“完成”
      if (count === 1) {
        document.getElementsByClassName('introjs-fullbutton')[0].innerHTML = '开始吧'
      }
      if (count === 2) {
        Vuex.commit('set_data', {
          guideChange: 'XXX',
        })
      }
    })
    .oncomplete(function (targetElement: any) {
      // 点击完成以及跳过按钮后执行的事件,不区分完成和跳过。
      console.log('这个是跳出或者完成')
    })
    .onexit(function (targetElement: any) {
      // 点击完成按钮后, 执行的事件
      if (isSkip) {
        return
      }
      setTimeout(() => {
        judgeCount()
      }, 200)
    })
    // eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    .onskip(function (targetElement: any) {
      // 点击跳过按钮后, 执行的事件
      // 存储进缓存,下次进入新手引导路由页时将不在触发Intro.js
      isSkip = true
      localStorage.setItem('isIntro', JSON.stringify({ nextGuideName: '', state: 0 }))
    })
    .start()
}

// 这个是每一步新手引导对应的点击下一步时对应应该进行的操做
function judgeCount() {
  switch (count) {
    case 1:
    case 2:
      guide([
        {
          title: 'XX模板',
          intro:
            'XX模板 中有丰富的模板,您能够“使用模板” 快速制做。固然,您也能够新建一个空白的XX。',
          element: document.querySelector('#guide-step3'),
          position: 'right',
        },
      ])
      break
    case 3:
      localStorage.setItem('isIntro', JSON.stringify({ nextGuideName: 'page1', state: 1 }))
      window.postMessage({ startGuide: true }, '*')
      break
    case 4:
      localStorage.setItem('isIntro', JSON.stringify({ nextGuideName: 'page2', state: 1 }))
      window.postMessage({ startCRMGuide: true }, '*')
      break
  }
}

复制代码

如下代码是放在你所须要的引导的.vue页面中,将他放入mounted中,vue2和3均可以,或者放入函数中经过点击事件触发均可以。架构

let i = setInterval(() => {
        guide([
          {
          // title: '新手教程',
          intro:
               'Hi,我是您的小助理,您能够随时点击这里召唤我,接下来让我带您熟悉一下操做流程吧!',
          element: document.querySelector('#guide-step1'),
          position: 'right',
         },
          {
            title: 'XX中心',
            intro:
              '左侧的“XX”菜单里包含 XXX、XX、XXX 三大应用,如今让咱们从“XXX”应用开始了解吧!',
            element: document.querySelector('#guide-step2'),
            position: 'right',
          },
        ])
        clearInterval(i)
      }, 500)
复制代码

以上主要是以前那位博主的思路,我加了些vue3+ts的写法,个人跨页面跨服务也基本采用他的思路,具体没看明白的能够先看他那篇。连接在最开头。框架


分布详解

除了以上原博主封装的方法外,还能够这么玩。dom

intro截图2.png

直接在每一步的对象内,写自定义的属性值,而后在封装的js里来作处理。 ide

这边用来处理刚刚写的自定义的属性值
.onexit(function () {
      // 点击完成按钮后, 执行的事件
      const { callback } = introSteps[count - 1]  //结构刚刚添加的callback属性值
      if (callback) {
        handleCallback(callback)
      }
    })
复制代码

这边用来处理刚刚自定义方法的回调函数

// 处理callback回调方法
function handleCallback(callback) {
  switch (callback) {
    case 'openKnowledgeManagementMenuEdit':
      localStorage.setItem('startGuide', 'edit')
      openXXXXXXXXX()
      break
    case 'XXXXXXXXXXXXXXXXXX':
      localStorage.setItem('XXXXXXXXXXXX', 'XXXXXXXXXXX')
      openXXXXXX()
      break
  }
}
复制代码

下面我来讲下qiankun中微服务,主框架和子框架如何经过联动经行引导。

两个方法:

  1. 经过缓存经行信息传递和触发。亲测比较麻烦不方便。
  2. 经过window.postMessage

传递模块

//在须要传递的框架中.onexit来触发这个方法
 case 4:
      localStorage.setItem('isIntro', JSON.stringify({ nextGuideName: 'page2', state: 1 }))
      window.postMessage({ startCRMGuide: true }, '*')
      break
复制代码

接收模块

//在子框架中你须要触发引导的界面中使用
   window.addEventListener('message', (message) => {
        const { data } = message
        if (data && data.startGuide) {
            guide([
          {
          // title: ''XX中心',
          intro:
               '左侧的“XX”菜单里包含 XXX、XX、XXX 三大应用,如今让咱们从“XXX”应用开始了解吧!',
          element: document.querySelector('#guide-step1'),
          position: 'right',
         },
          {
            title: 'XX中心',
            intro:
              '左侧的“XX”菜单里包含 XXX、XX、XXX 三大应用,如今让咱们从“XXX”应用开始了解吧!',
            element: document.querySelector('#guide-step2'),
            position: 'right',
          },
        ])
        }
      })

复制代码

用法主要就是传递这块。

样式修改

使用qiankun的框架的话全部的样式直接写到主框架里就好了

例如 想修改跳出按钮的位置和样式,直接在以下图跳出按钮内添加一个标签就行(我这里加了个div)

intro3截图.png

css以下,这个就不解释了应该看的懂,直接放入主框架全局样式

.introjs-skipbutton {
  position: fixed;
  right: 45%;
  top: 20px;

  >div {
    width: 56px;
    height: 74px;
    background: url(./XXXXX.png) no-repeat;
    background-size: cover;
    cursor: pointer;
  }
}

复制代码

若是你想隐藏某个按钮也能够经过样式来直接控制,按照intro的每一个按钮类名。

例如:想隐藏上一步这个按钮

//上一步按钮
.introjs-prevbutton {
  display: none !important;
}
复制代码

下面来讲一说坑

以下这个方法onskip官方API是没有公布出来的,我也是看了原博主的文章也去翻源码了,发现确实是有。

你要是vue2且没用ts的话,和原博主同样直接用就好了。但你要是VUE3+ts那可要了命了他官方的@type/intro.js是没有暴露这个方法的会一直报错。必须加上下面的注释才能在编译和打包的时候不出错。(唉,说多了都是泪,竟然两行注释解决了)

// eslint-disable-next-line @typescript-eslint/ban-ts-comment
    // @ts-ignore
    .onskip(function (targetElement: any) {
      // 点击跳过按钮后, 执行的事件
      // 存储进缓存,下次进入新手引导路由页时将不在触发Intro.js
      isSkip = true
      localStorage.setItem('isIntro', JSON.stringify({ nextGuideName: '', state: 0 }))
    })
复制代码

第二个坑

就是引选中一个按钮,被选中的按钮依然是能够点击的

intro4截图.png

好比这个是一个按钮的引导,这个编辑依然能够点击,这个时候点击就会出现一些问题,那如何来阻止。

相信很多朋友确定和我同样想到用css的pointer-events,或者用js来阻止。

可是真的不用,就在我就纠结的时候我同事发现只需调整z-index就能够了,显示效果不变。

//只需加入这个就能够阻止
.introjs-helperLayer {
  z-index: 9999999 !important;
}
复制代码

第三个坑 若是你在引导的过程当中有些自动的弹窗出现,它是不会关闭的,须要手动关闭。

//能够在须要的地方加上这个两行
import introJs from 'intro.js'
  introJs().exit()
复制代码

准备下班,今天就写到这里,原本想继续写intro.js和Dirver.js的区别。

相关文章
相关标签/搜索