Skip to content

用户引导

Vue 用户引导和产品导览工具。

Driver.js

基本信息

特点

  • ✅ 轻量级(~5KB gzipped)
  • ✅ 无依赖
  • ✅ 高度可定制
  • ✅ 支持键盘导航
  • ✅ TypeScript 支持
  • ✅ 响应式设计
  • ✅ 支持暗黑模式

安装

bash
npm install driver.js
bash
pnpm add driver.js
bash
yarn add driver.js
bash
bun add driver.js

基础用法

1. 简单的单步引导

vue
<script setup lang="ts">
import { driver } from 'driver.js'
import 'driver.js/dist/driver.css'

const showGuide = () => {
  const driverObj = driver({
    showProgress: true,
    steps: [
      {
        element: '#step1',
        popover: {
          title: '欢迎',
          description: '这是第一步引导'
        }
      }
    ]
  })
  
  driverObj.drive()
}
</script>

<template>
  <div>
    <button @click="showGuide">开始引导</button>
    <div id="step1">这是需要高亮的元素</div>
  </div>
</template>

2. 多步引导流程

vue
<script setup lang="ts">
import { ref } from 'vue'
import { driver } from 'driver.js'
import 'driver.js/dist/driver.css'

const startTour = () => {
  const driverObj = driver({
    showProgress: true,
    showButtons: ['next', 'previous', 'close'],
    steps: [
      {
        element: '#header',
        popover: {
          title: '导航栏',
          description: '这里是网站的主导航栏',
          side: 'bottom',
          align: 'start'
        }
      },
      {
        element: '#sidebar',
        popover: {
          title: '侧边栏',
          description: '这里可以快速访问各个功能模块',
          side: 'right',
          align: 'start'
        }
      },
      {
        element: '#content',
        popover: {
          title: '内容区域',
          description: '这里显示主要内容',
          side: 'top',
          align: 'center'
        }
      }
    ]
  })
  
  driverObj.drive()
}
</script>

<template>
  <div>
    <button @click="startTour">开始导览</button>
    <header id="header">导航栏</header>
    <aside id="sidebar">侧边栏</aside>
    <main id="content">内容区域</main>
  </div>
</template>

3. 高级配置

vue
<script setup lang="ts">
import { driver } from 'driver.js'
import 'driver.js/dist/driver.css'

const advancedTour = () => {
  const driverObj = driver({
    // 显示进度
    showProgress: true,
    
    // 自定义按钮
    showButtons: ['next', 'previous', 'close'],
    
    // 按钮文本
    nextBtnText: '下一步',
    prevBtnText: '上一步',
    doneBtnText: '完成',
    
    // 动画
    animate: true,
    
    // 平滑滚动
    smoothScroll: true,
    
    // 允许点击背景关闭
    allowClose: true,
    
    // 覆盖层透明度
    overlayOpacity: 0.5,
    
    // 生命周期钩子
    onDestroyStarted: () => {
      if (!confirm('确定要退出引导吗?')) {
        driverObj.drive()
      }
    },
    
    onDestroyed: () => {
      console.log('引导已结束')
    },
    
    steps: [
      {
        element: '#feature1',
        popover: {
          title: '功能一',
          description: '这是功能一的说明',
          side: 'left',
          align: 'start',
          
          // 自定义按钮
          showButtons: ['next', 'close'],
          
          // 步骤回调
          onNextClick: () => {
            console.log('点击了下一步')
            driverObj.moveNext()
          },
          
          onPrevClick: () => {
            driverObj.movePrevious()
          }
        }
      },
      {
        element: '#feature2',
        popover: {
          title: '功能二',
          description: '这是功能二的说明',
          side: 'right'
        }
      }
    ]
  })
  
  driverObj.drive()
}
</script>

<template>
  <div>
    <button @click="advancedTour">高级引导</button>
    <div id="feature1">功能一</div>
    <div id="feature2">功能二</div>
  </div>
</template>

常用配置选项

全局配置

选项类型默认值说明
animatebooleantrue是否启用动画
smoothScrollbooleanfalse是否平滑滚动
allowClosebooleantrue是否允许点击背景关闭
overlayOpacitynumber0.5覆盖层透明度
showProgressbooleanfalse是否显示进度
showButtonsstring[]['next', 'previous', 'close']显示的按钮
nextBtnTextstring'Next'下一步按钮文本
prevBtnTextstring'Previous'上一步按钮文本
doneBtnTextstring'Done'完成按钮文本

Popover 配置

选项类型说明
titlestring标题
descriptionstring描述内容
side'top' | 'right' | 'bottom' | 'left'弹出位置
align'start' | 'center' | 'end'对齐方式
showButtonsstring[]显示的按钮

实用场景

1. 首次访问引导

vue
<script setup lang="ts">
import { onMounted } from 'vue'
import { driver } from 'driver.js'
import 'driver.js/dist/driver.css'

onMounted(() => {
  // 检查是否是首次访问
  const hasVisited = localStorage.getItem('hasVisited')
  
  if (!hasVisited) {
    const driverObj = driver({
      showProgress: true,
      steps: [
        {
          popover: {
            title: '欢迎使用!',
            description: '让我们快速了解一下主要功能'
          }
        },
        {
          element: '#main-feature',
          popover: {
            title: '主要功能',
            description: '这是我们的核心功能'
          }
        }
      ],
      onDestroyed: () => {
        localStorage.setItem('hasVisited', 'true')
      }
    })
    
    driverObj.drive()
  }
})
</script>

<template>
  <div>
    <div id="main-feature">主要功能区域</div>
  </div>
</template>

2. 新功能提示

vue
<script setup lang="ts">
import { ref } from 'vue'
import { driver } from 'driver.js'
import 'driver.js/dist/driver.css'

const showNewFeature = () => {
  const driverObj = driver({
    steps: [
      {
        element: '#new-feature',
        popover: {
          title: '🎉 新功能上线',
          description: '我们新增了这个强大的功能,快来试试吧!',
          side: 'bottom',
          showButtons: ['close']
        }
      }
    ]
  })
  
  driverObj.drive()
}

// 检查版本号,显示新功能提示
const checkNewFeatures = () => {
  const lastVersion = localStorage.getItem('lastVersion')
  const currentVersion = '2.0.0'
  
  if (lastVersion !== currentVersion) {
    showNewFeature()
    localStorage.setItem('lastVersion', currentVersion)
  }
}
</script>

<template>
  <div>
    <div id="new-feature">新功能按钮</div>
  </div>
</template>

3. 表单填写引导

vue
<script setup lang="ts">
import { driver } from 'driver.js'
import 'driver.js/dist/driver.css'

const guideForm = () => {
  const driverObj = driver({
    showProgress: true,
    steps: [
      {
        element: '#username',
        popover: {
          title: '用户名',
          description: '请输入您的用户名,4-20个字符',
          side: 'right'
        }
      },
      {
        element: '#email',
        popover: {
          title: '邮箱',
          description: '请输入有效的邮箱地址',
          side: 'right'
        }
      },
      {
        element: '#password',
        popover: {
          title: '密码',
          description: '密码至少8位,包含字母和数字',
          side: 'right'
        }
      },
      {
        element: '#submit',
        popover: {
          title: '提交',
          description: '填写完成后点击提交按钮',
          side: 'top'
        }
      }
    ]
  })
  
  driverObj.drive()
}
</script>

<template>
  <form>
    <input id="username" type="text" placeholder="用户名" />
    <input id="email" type="email" placeholder="邮箱" />
    <input id="password" type="password" placeholder="密码" />
    <button id="submit" type="submit">提交</button>
    <button type="button" @click="guideForm">查看填写指南</button>
  </form>
</template>

自定义样式

vue
<script setup lang="ts">
import { driver } from 'driver.js'
import 'driver.js/dist/driver.css'

const customStyleTour = () => {
  const driverObj = driver({
    steps: [
      {
        element: '#custom',
        popover: {
          title: '自定义样式',
          description: '这是一个自定义样式的引导',
          popoverClass: 'custom-popover'
        }
      }
    ]
  })
  
  driverObj.drive()
}
</script>

<template>
  <div>
    <button @click="customStyleTour">自定义样式引导</button>
    <div id="custom">内容</div>
  </div>
</template>

<style>
/* 自定义弹出框样式 */
.custom-popover {
  background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
  color: white;
}

.custom-popover .driver-popover-title {
  color: white;
  font-size: 20px;
}

.custom-popover .driver-popover-description {
  color: rgba(255, 255, 255, 0.9);
}

.custom-popover .driver-popover-next-btn {
  background: white;
  color: #667eea;
}
</style>

Composable 封装

创建可复用的 composable:

typescript
// composables/useDriverGuide.ts
import { driver, type Config, type DriveStep } from 'driver.js'
import 'driver.js/dist/driver.css'

export function useDriverGuide() {
  const createGuide = (config?: Config) => {
    return driver({
      showProgress: true,
      showButtons: ['next', 'previous', 'close'],
      nextBtnText: '下一步',
      prevBtnText: '上一步',
      doneBtnText: '完成',
      ...config
    })
  }

  const startGuide = (steps: DriveStep[], config?: Config) => {
    const driverObj = createGuide({ ...config, steps })
    driverObj.drive()
    return driverObj
  }

  const highlightElement = (element: string, config?: Config) => {
    const driverObj = createGuide(config)
    driverObj.highlight({
      element,
      popover: config?.steps?.[0]?.popover
    })
    return driverObj
  }

  return {
    createGuide,
    startGuide,
    highlightElement
  }
}

使用 composable:

vue
<script setup lang="ts">
import { useDriverGuide } from '@/composables/useDriverGuide'

const { startGuide } = useDriverGuide()

const showTour = () => {
  startGuide([
    {
      element: '#step1',
      popover: {
        title: '步骤一',
        description: '这是第一步'
      }
    },
    {
      element: '#step2',
      popover: {
        title: '步骤二',
        description: '这是第二步'
      }
    }
  ])
}
</script>

<template>
  <div>
    <button @click="showTour">开始引导</button>
    <div id="step1">步骤一</div>
    <div id="step2">步骤二</div>
  </div>
</template>

最佳实践

1. 避免过长的引导流程

  • 将引导步骤控制在 5-7 步以内
  • 过长的流程可以分成多个小引导

2. 合理的触发时机

  • 首次访问时自动触发
  • 新功能发布时提示
  • 用户主动请求帮助时

3. 提供跳过选项

  • 始终允许用户跳过引导
  • 提供"不再显示"选项

4. 响应式设计

  • 确保在不同屏幕尺寸下都能正常显示
  • 移动端考虑使用更简洁的引导

5. 本地化

  • 根据用户语言显示对应文本
  • 使用 i18n 管理引导文本
vue
<script setup lang="ts">
import { useI18n } from 'vue-i18n'
import { driver } from 'driver.js'
import 'driver.js/dist/driver.css'

const { t } = useI18n()

const startLocalizedTour = () => {
  const driverObj = driver({
    nextBtnText: t('guide.next'),
    prevBtnText: t('guide.prev'),
    doneBtnText: t('guide.done'),
    steps: [
      {
        element: '#feature',
        popover: {
          title: t('guide.feature.title'),
          description: t('guide.feature.description')
        }
      }
    ]
  })
  
  driverObj.drive()
}
</script>

与其他引导库对比

特性Driver.jsIntro.jsShepherd.js
体积~5KB~10KB~20KB
依赖Popper.js
TypeScript⚠️
自定义样式✅✅✅✅
键盘导航
移动端支持
学习曲线

推荐场景

  • 新用户引导 - 帮助新用户快速了解产品
  • 功能介绍 - 介绍新功能或复杂功能
  • 操作提示 - 引导用户完成特定操作
  • 表单填写 - 指导用户正确填写表单
  • 功能发现 - 帮助用户发现隐藏功能

其他引导库

Intro.js

基本信息

特点

  • ✅ 功能完善
  • ✅ 主题丰富
  • ✅ 支持提示框
  • ⚠️ 体积较大

Shepherd.js

基本信息

特点

  • ✅ 高度可定制
  • ✅ 框架集成
  • ✅ 丰富的 API
  • ⚠️ 依赖 Popper.js

vue-tour

基本信息

特点

  • ✅ Vue 原生组件
  • ✅ 声明式使用
  • ⚠️ 仅支持 Vue 2

总结

推荐使用 Driver.js,因为:

  • 轻量级,性能优秀
  • 无依赖,易于集成
  • API 简洁,易于使用
  • TypeScript 支持完善
  • 高度可定制
  • 活跃维护

对于 Vue 3 项目,Driver.js 是最佳选择。