Skip to content

Guide(新手导引)使用指南

一个轻量级的 React 新手导引组件,无需第三方库依赖。

特性

✅ 蒙层高亮指定元素 ✅ 自动定位 popover(智能上下位置) ✅ 上一步 / 下一步导航 ✅ 进度显示 ✅ 响应式设计 ✅ 首次访问自动出现(localStorage 记录)

文件结构

useGuide.ts          # Hook,管理导引状态和逻辑
GuideOverlay.tsx     # 蒙层和提示框组件
GuideOverlay.css     # 样式
GuideExample.tsx     # 使用示例

快速开始

1. 定义导引步骤

tsx
const GUIDE_STEPS = [
  {
    selector: '#search-input', // CSS 选择器
    title: '搜索功能', // 标题(可选)
    description: '快速搜索文档', // 描述(可选)
  },
  // ...更多步骤
];

2. 在组件中使用

tsx
import { useGuide } from './useGuide';
import { GuideOverlay } from './GuideOverlay';

function MyComponent() {
  const guide = useGuide(GUIDE_STEPS);

  return (
    <>
      <GuideOverlay
        isRunning={guide.isRunning}
        targetRect={guide.targetRect}
        title={guide.step?.title}
        description={guide.step?.description}
        currentStep={guide.currentStep}
        totalSteps={GUIDE_STEPS.length}
        onNext={guide.next}
        onPrev={guide.prev}
        onClose={guide.stop}
      />

      {/* 你的页面内容 */}
      <div id="search-input">搜索框</div>
    </>
  );
}

3. 首次访问自动启动(可选)

tsx
useEffect(() => {
  if (!localStorage.getItem('guide_done')) {
    guide.start();
    localStorage.setItem('guide_done', '1');
  }
}, []);

4. 提供"重新查看"按钮

tsx
<button
  onClick={() => {
    guide.start();
    localStorage.removeItem('guide_done');
  }}
>
  重新查看导引
</button>

API 文档

useGuide(steps)

参数:

  • steps: GuideStep[] - 导引步骤数组

返回值:

ts
{
  isRunning: boolean;      // 是否正在运行
  currentStep: number;     // 当前步骤索引
  targetRect: DOMRect | null;  // 目标元素的位置信息
  step: GuideStep;         // 当前步骤的内容
  start(): void;           // 启动导引
  stop(): void;            // 停止导引
  next(): void;            // 下一步
  prev(): void;            // 上一步
}

GuideStep

ts
interface GuideStep {
  selector: string; // CSS 选择器(必需)
  title?: string; // 标题
  description?: string; // 描述
}

高级用法

动态添加步骤

tsx
const [steps, setSteps] = useState(INITIAL_STEPS);
const guide = useGuide(steps);

// 后来添加新的引导步骤
const addNewGuideStep = () => {
  setSteps([...steps, { selector: '#new-feature', title: '新功能', description: '...' }]);
};

路由切换时暂停

tsx
import { useLocation } from 'react-router-dom';

function MyComponent() {
  const guide = useGuide(GUIDE_STEPS);
  const location = useLocation();

  useEffect(() => {
    // 路由变化时停止导引
    guide.stop();
  }, [location]);
}

自定义样式

编辑 GuideOverlay.css 中的 CSS 变量或类名:

css
.guide-overlay {
  background: rgba(0, 0, 0, 0.6); /* 改变蒙层透明度 */
}

.guide-highlight {
  border: 3px solid #ff6b6b; /* 改变高亮色 */
}

.guide-btn-primary {
  background: #ff6b6b; /* 改变按钮颜色 */
}

常见问题

Q:目标元素找不到怎么办?

A:确保选择器正确,元素已经渲染。可以在 useEffect 中延迟启动:

tsx
useEffect(() => {
  setTimeout(() => guide.start(), 500);
}, []);

Q:popover 位置不对?

A:在 GuideOverlay.tsx 中的 setPopoverPos 函数修改位置计算逻辑。

Q:能否跳过某个步骤?

A:可以在 GUIDE_STEPS 中注释掉对应步骤,或者用条件渲染。

Q:支持移动端吗?

A:支持。GuideOverlay.css 中已包含响应式设计。

与 driver.js 的对比

功能本实现driver.js
大小~4KB~15KB
依赖0(React 原生)0
蒙层效果
自动定位✅✅(更智能)
键盘导航
动画效果✅✅
学习成本中等

扩展建议

想要增强功能,可以添加:

  1. 键盘导航:ESC 关闭,← → 上下页
  2. 鼠标跳过:点击蒙层关闭
  3. 自定义 render:允许自定义 popover 渲染
  4. 滚动自动跟踪:元素滚出视图时自动滚动到视图
  5. 多语言支持:翻译按钮文案

License

MIT - 自由使用

内容仅供学习参考,如有错误欢迎指正与 PR