新手引导组件(通用方案shepherd.js)

3,660 阅读3分钟

一、开发背景

业务开发中需要使用到新手引导来给用户一个更好的体验,但目前公司前端使用的技术栈有vue和react,所以需要设计一款通用方案来高效开发,并且约束后续所有类似业务开发,达成一致。

二、开发技术调研

目前社区有许多新手引导组件,但是都是基于一种框架,要么vue,要么react;基于原生开发的又使用麻烦,并且维护人员少。

经过调研后,最终采取 shepherd.js 。

官网:shepherdjs.dev

github:github.com

优点:

  • api文档简介明了,提供案例,阅读友好

  • 提供多种版本的新手引导组件,便于高效开发

  • 点赞数高达10.6K,社区环境好

三、项目开发

基于公司前端技术,分成两类,分别做案例代码:

一、react版本

1、安装

npm install --save react-shepherd

2、用法

import React, { Component, useContext } from 'react'
import { ShepherdTour, ShepherdTourContext } from 'react-shepherd'
import newSteps from './steps'

const tourOptions = {
  defaultStepOptions: {
    cancelIcon: {
      enabled: true
    }
  },
  useModalOverlay: true
};

function Button() {
  const tour = useContext(ShepherdTourContext);

  return (
    <button className="button dark" onClick={tour.start}>
      Start Tour
    </button>
  );
}

class App extends Component {
  render() {
    return (
      <div>
        <ShepherdTour steps={newSteps} tourOptions={tourOptions}>
          <Button />
        </ShepherdTour>
      </div>
    );
  }
}

3、添加配置步骤项

const steps = [
  {
    id: 'intro',
    attachTo: { element: '.first-element', on: 'bottom' },
    beforeShowPromise: function () {
      return new Promise(function (resolve) {
        setTimeout(function () {
          window.scrollTo(0, 0);
          resolve();
        }, 500);
      });
    },
    buttons: [
      {
        classes: 'shepherd-button-secondary',
        text: 'Exit',
        type: 'cancel'
      },
      {
        classes: 'shepherd-button-primary',
        text: 'Back',
        type: 'back'
      },
      {
        classes: 'shepherd-button-primary',
        text: 'Next',
        type: 'next'
      }
    ],
    classes: 'custom-class-name-1 custom-class-name-2',
    highlightClass: 'highlight',
    scrollTo: false,
    cancelIcon: {
      enabled: true,
    },
    title: 'Welcome to React-Shepherd!',
    text: ['React-Shepherd is a JavaScript library for guiding users through your React app.'],
    when: {
      show: () => {
        console.log('show step');
      },
      hide: () => {
        console.log('hide step');
      }
    }
  },
  // ...
];

完整代码如下:(弹窗内部新手引导案例)

import React, { useContext, useEffect, useState } from 'react'
import { ShepherdTour, ShepherdTourContext, ShepherdOptionsWithType } from 'react-shepherd'
import 'shepherd.js/dist/css/shepherd.css'
import { Button, Drawer } from 'antd'

const Test = () => {
  const [open, setOpen] = useState(false)

  const showDrawer = () => {
    setOpen(true)
    console.log(true)
  }

  const onClose = () => {
    setOpen(false)
  }

  const newSteps: ShepherdOptionsWithType[] = [
    {
      id: 'intro',
      attachTo: { element: '.h1', on: 'bottom' },
      beforeShowPromise() {
        return new Promise(function (resolve) {
          setTimeout(function () {
            window.scrollTo(0, 0)
            resolve(null)
          }, 500)
        })
      },
      buttons: [
        {
          classes: 'shepherd-button-secondary',
          text: '跳过',
          type: 'cancel'
        },
        {
          classes: 'shepherd-button-primary',
          text: '上一步',
          type: 'back'
        },
        {
          classes: 'shepherd-button-primary',
          text: '下一步',
          type: 'next'
        }
      ],
      classes: 'custom-class-name-1 custom-class-name-2',
      highlightClass: 'highlight',
      scrollTo: false,
      cancelIcon: {
        enabled: true
      },
      title: '第一步',
      text: ['React-Shepherd is a JavaScript library for guiding users through your React app.'],
      when: {
        show: () => {
          console.log('show step')
        },
        hide: () => {
          console.log('hide step')
          showDrawer()
        }
      }
    },
    {
      id: 'intro',
      attachTo: { element: '.two', on: 'bottom' },
      beforeShowPromise() {
        return new Promise(function (resolve) {
          setTimeout(function () {
            window.scrollTo(0, 0)
            resolve(null)
          }, 500)
        })
      },
      buttons: [
        {
          classes: 'shepherd-button-secondary',
          text: '跳过',
          type: 'cancel'
        },
        {
          classes: 'shepherd-button-primary',
          text: '上一步',
          type: 'back'
        },
        {
          classes: 'shepherd-button-primary',
          text: '下一步',
          type: 'next'
        }
      ],
      classes: 'custom-class-name-1 custom-class-name-2',
      highlightClass: 'highlight',
      scrollTo: false,
      cancelIcon: {
        enabled: true
      },
      title: '第二步',
      text: ['React-Shepherd is a JavaScript library for guiding users through your React app.'],
      when: {
        show: () => {
          console.log('show step')
        },
        hide: () => {
          console.log('hide step')
        }
      }
    }
    // ...
  ]

  return (
    <div>
      <h1 className='h1'>AI 外呼 部分使用react写的项目</h1>

      <ShepherdTour steps={newSteps} tourOptions={tourOptions}>
        <MyButton />
      </ShepherdTour>

      <div>
        <p>展示1111</p>
        <p>展示222</p>
      </div>

      <Button type='primary' onClick={showDrawer}>
        Open
      </Button>

      <Drawer title='Basic Drawer' placement='right' onClose={onClose} visible={open}>
        <p className='two'>Some contents...</p>
        <p>Some contents...</p>
        <p>Some contents...</p>
      </Drawer>
    </div>
  )
}

const tourOptions = {
  defaultStepOptions: {
    cancelIcon: {
      enabled: true
    }
  },
  useModalOverlay: true
}

function MyButton() {
  const tour = useContext(ShepherdTourContext)

  // useEffect(() => {
  //   tour.start()
  // }, [])

  return (
    // eslint-disable-next-line react/button-has-type
    <button className='button dark' onClick={tour.start}>
      Start Tour
    </button>
  )
}

export default Test

二、vue版本

注:node版本需要14以上

1、安装

npm install vue-shepherd shepherd.js --save

2、引入

import Vue from 'vue';
import VueShepherd from 'vue-shepherd';
import 'shepherd.js/dist/css/shepherd.css';

Vue.use(VueShepherd);

3、使用

<template>
  <div ref='dom'>
    Testing
  </div>
</template>

<script>
  export default {
    name: 'ShepherdExample',
    mounted() {
      this.$nextTick(() => {
        const tour = this.$shepherd({
          useModalOverlay: true
        });

        tour.addStep({
          attachTo: { element: this.$refs.dom, on: 'top' },
          text: 'Test'
        });

        tour.start();
      });
    }
  };
</script>

注意:

二者都是基于shepherd.js封装而来,所以跨框架使用没什么难度,用法都差不多,只需要在 每个 `step` 中写入配置项即可