docs: 更新模板使用文档
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
1 parent
17fee63a16
commit
a98b1d383e
1 file changed
+535
-15
@@ -1,18 +1,24 @@
|
||||
# React Vite Template
|
||||
# 易班 H5 开发模板
|
||||
|
||||
一个基于 React 19、TypeScript、Vite、React Router 和 Tailwind CSS 的前端项目模板。
|
||||
一个基于 React 19、TypeScript、Vite、React Router、Tailwind CSS 和 Zustand 的易班平台 H5 开发模板。
|
||||
|
||||
## 特性
|
||||
|
||||
- React 19 + TypeScript
|
||||
- Vite 6 开发与构建
|
||||
- React Router 7 路由管理
|
||||
- 路由页面懒加载
|
||||
- Tailwind CSS 4
|
||||
- Vite 8 开发与构建
|
||||
- React Router 7 路由管理(支持懒加载)
|
||||
- Tailwind CSS 4 原子化样式
|
||||
- Zustand 轻量状态管理
|
||||
- Biome 代码格式化与检查
|
||||
- Husky + lint-staged 提交前检查
|
||||
- 1920x1080 整体缩放适配
|
||||
- 横屏访问提示
|
||||
- vconsole 移动端调试工具(仅开发环境)
|
||||
- 易班 videoajax.js 封装
|
||||
- 易班用户信息状态管理
|
||||
- `@` 指向 `src` 的路径别名
|
||||
- 组件分层:通用组件、业务组件、页面组件
|
||||
- 通过 `@yuxiang/cli` 安装并提交可直接修改的课程交互源码
|
||||
- 组件分层:Registry copied source、模板适配器、业务组件、页面组件
|
||||
|
||||
## 使用模板
|
||||
|
||||
@@ -33,24 +39,113 @@ bun dev
|
||||
### 通过 GitHub CLI 创建
|
||||
|
||||
```bash
|
||||
gh repo create my-react-app --template your-name/react-vite-template --public
|
||||
gh repo create my-react-app --template your-name/react-template --public
|
||||
cd my-react-app
|
||||
bun install
|
||||
bun dev
|
||||
```
|
||||
|
||||
创建项目后,建议修改 [package.json](package.json) 中的 `name` 字段。
|
||||
创建项目后,建议修改 [package.json](package.json) 中的 `name` 字段,以及 [src/app.config.ts](src/app.config.ts) 中的页面标题、描述和图标配置。
|
||||
|
||||
## 应用配置
|
||||
|
||||
页面标签页标题、描述、图标和 viewport 配置统一维护在 [src/app.config.ts](src/app.config.ts):
|
||||
|
||||
```ts
|
||||
export const appConfig = {
|
||||
title: "React Vite App",
|
||||
description: "易班 H5 课程模板",
|
||||
favicon: "./vite.svg",
|
||||
design: {
|
||||
width: 1920,
|
||||
height: 1080,
|
||||
},
|
||||
scale: {
|
||||
max: 1,
|
||||
},
|
||||
viewport: {
|
||||
width: "device-width",
|
||||
initialScale: 1.0,
|
||||
minimumScale: 1.0,
|
||||
maximumScale: 1.0,
|
||||
},
|
||||
};
|
||||
```
|
||||
|
||||
修改该配置后需要重启开发服务。
|
||||
|
||||
## 开发命令
|
||||
|
||||
```bash
|
||||
bun dev # 启动开发服务器
|
||||
bun build # 类型检查并构建生产版本
|
||||
bun preview # 预览生产构建
|
||||
bun lint # 代码检查
|
||||
bun lint:fix # 自动修复代码问题
|
||||
bun run build # 类型检查并构建生产版本
|
||||
bun run preview # 预览生产构建
|
||||
bun run lint # 代码检查
|
||||
bun run lint:fix # 自动修复代码问题
|
||||
```
|
||||
|
||||
## 开发规范
|
||||
|
||||
完整的 Claude Code/自动化开发规范见 [CLAUDE.md](CLAUDE.md)。日常开发遵守以下约定:
|
||||
|
||||
- 使用 Bun 执行项目脚本,提交前确保 `bun run lint` 通过;涉及路由、构建配置、页面结构或类型系统的改动建议同时运行 `bun run build`。
|
||||
- 代码风格以 [biome.json](biome.json) 为准:tab 缩进、双引号、Biome 检查和导入整理。
|
||||
- 组件、页面、store、API 的类型不要和实现代码写在同一个文件;组件类型放同目录 `组件名.types.ts`,store 类型放 [src/stores/types/](src/stores/types/),跨模块共享类型才放入 [src/types/](src/types/)。
|
||||
- 短的静态 Tailwind class 可直接写在 JSX 中;只有需要条件合并、外部 `className`、冲突合并或组合 CSS Module 时才使用 `cn`。
|
||||
- Tailwind class 过长、重复、条件组合复杂,或直接实现过于冗余时,再提取为局部常量、同目录文件、CSS Module 或通用组件。
|
||||
- 新增页面沿用 [src/router/index.tsx](src/router/index.tsx) 中的 `lazyRoute` 和 `RouteFallback` 模式,导入优先使用 `@` 指向 `src` 的路径别名。
|
||||
- 新增通用组件时,按需维护 [src/components/common/index.ts](src/components/common/index.ts),并考虑在 [src/pages/Components/index.tsx](src/pages/Components/index.tsx) 补充示例。
|
||||
|
||||
## 课程交互源码
|
||||
|
||||
模板中的基础组件和课程交互不是外部 React 运行时包,而是由 `@yuxiang/cli` 复制并提交到当前项目:
|
||||
|
||||
```text
|
||||
src/components/ui/ # Button、Portal、Overlay、Toast
|
||||
src/components/course-interactions/ # GuideDialog、GuideSpotlight、DragDrop
|
||||
src/course-runtime/ # 固定课程画布运行时
|
||||
src/lib/cn.ts # 本地 class 合并工具
|
||||
```
|
||||
|
||||
项目根目录的 [components.json](components.json) 配置 copied source 的目录与 alias。需要新增能力时运行:
|
||||
|
||||
```bash
|
||||
bunx @yuxiang/cli add <item>
|
||||
```
|
||||
|
||||
CLI 默认不会覆盖不同内容的本地文件。安装后请把源码作为模板代码维护,不要重新添加 `@yuxiang/react` 或 `@yuxiang/core` 依赖。
|
||||
|
||||
## 真实课程案例
|
||||
|
||||
本地打开以下路由可体验连贯的课程流程:
|
||||
|
||||
```text
|
||||
http://localhost:5173/#/course-demo
|
||||
```
|
||||
|
||||
案例包含课程导入与分支、页面 Spotlight、课程资源分类拖拽、错误/正确 Toast、完成 Overlay,以及易班或 session fallback 的进度保存与刷新恢复。
|
||||
|
||||
## 组件开发 Smoke 页
|
||||
|
||||
本地开发时可以打开组件示例页查看和测试基础组件:
|
||||
|
||||
```text
|
||||
http://localhost:5173/#/components
|
||||
```
|
||||
|
||||
该路由仅用于开发时检查 copied source 的基础状态,不作为产品级组件展示墙。真实组合用法以 `#/course-demo` 为准。
|
||||
|
||||
当前 smoke 页包含:
|
||||
|
||||
- `Button`: variant 和 size 示例
|
||||
- `Toast`: info / success / warning / error 轻提示示例
|
||||
- `Portal`: 挂载到 `document.body` 或自定义容器的浮层示例
|
||||
- `Overlay`: 默认背景、自定义 Tailwind 背景、背景图片、禁止点击背景关闭等交互示例
|
||||
- `SpotlightGuide`: 课程引导和高亮目标区域示例
|
||||
- `Drag and Drop`: 基于 dnd-kit 的拖拽到目标区域示例
|
||||
|
||||
后续新增通用组件时,可以在 [src/pages/Components/index.tsx](src/pages/Components/index.tsx) 中补充对应示例。
|
||||
|
||||
## 目录结构
|
||||
|
||||
```text
|
||||
@@ -60,14 +155,439 @@ src/
|
||||
├── components/ # 组件
|
||||
│ ├── business/ # 业务组件
|
||||
│ └── common/ # 通用组件
|
||||
├── hooks/ # 自定义 Hooks
|
||||
├── pages/ # 页面组件
|
||||
├── router/ # 路由配置
|
||||
├── stores/ # Zustand 状态管理
|
||||
│ └── modules/ # 状态模块
|
||||
│ ├── app.ts # 应用状态
|
||||
│ └── user.ts # 易班用户状态
|
||||
├── styles/ # 全局样式
|
||||
├── types/ # TypeScript 类型
|
||||
└── utils/ # 工具函数
|
||||
├── useOrientation.ts # 横竖屏检测
|
||||
├── useScale.ts # 1920x1080 整体缩放
|
||||
├── vconsole.ts # 调试工具
|
||||
└── yiban.ts # 易班 API 封装
|
||||
```
|
||||
|
||||
## 易班开发说明
|
||||
|
||||
模板面向易班 H5 / 静态资源相对路径部署,Vite `base` 固定为 `"./"`,确保构建产物在未知子路径或压缩包上传场景下仍能引用资源。除非部署环境明确要求根路径资源,否则不要轻易改成 `"/"`。
|
||||
|
||||
### videoajax.js 使用
|
||||
|
||||
模板已集成易班 videoajax.js,提供以下功能:
|
||||
|
||||
- [public/videoajax/jquery-3.7.1.min.js](public/videoajax/jquery-3.7.1.min.js)
|
||||
- [public/videoajax/videoajax.js](public/videoajax/videoajax.js)
|
||||
|
||||
这些文件需要和构建后的页面同源、同相对路径部署。若易班平台提供了新的 `videoajax.js`,请同步确认来源、版本和分发权限后再替换,并重新验证用户数据、课程进度、断点和答题记录相关能力。
|
||||
|
||||
### 易班环境判断
|
||||
|
||||
模板启动时会从 URL 中读取:
|
||||
|
||||
- `courseId` / `courseid`
|
||||
- `uid`
|
||||
|
||||
生产环境中,只要存在以上任意参数,就会认为当前处于易班环境。
|
||||
|
||||
本地开发环境中,即使 URL 带有 `courseId` / `uid`,也默认使用 `sessionStorage`,避免误请求易班接口:
|
||||
|
||||
```text
|
||||
http://localhost:5173/?courseId=123&uid=456
|
||||
```
|
||||
|
||||
如果本地确实需要强制走易班接口,可追加:
|
||||
|
||||
```text
|
||||
http://localhost:5173/?courseId=123&uid=456&yiban=1
|
||||
```
|
||||
|
||||
模板已集成以下易班能力:
|
||||
|
||||
#### 1. 存取用户数据
|
||||
|
||||
```ts
|
||||
import { setUserStorage, getUserStorage } from '@/utils/yiban';
|
||||
|
||||
// 保存数据(自动根据易班连接状态选择存储方式)
|
||||
await setUserStorage(lessonId, key, value);
|
||||
|
||||
// 读取数据
|
||||
const result = await getUserStorage(lessonId, key);
|
||||
if (result.status === 'success') {
|
||||
console.log(result.content);
|
||||
}
|
||||
|
||||
// 强制指定存储方式
|
||||
await setUserStorage(lessonId, key, value, { backend: 'session' });
|
||||
```
|
||||
|
||||
#### 2. 课程进度管理
|
||||
|
||||
```ts
|
||||
import { reportCourseProgress, getCourseProgress } from '@/utils/yiban';
|
||||
|
||||
// 上报课程进度(自动读取 store 中的 courseId 和连接状态)
|
||||
await reportCourseProgress(order);
|
||||
|
||||
// 获取课程进度
|
||||
const progress = await getCourseProgress(order);
|
||||
if (progress) {
|
||||
console.log('当前进度:', progress.data.process);
|
||||
}
|
||||
```
|
||||
|
||||
#### 3. 播放断点管理
|
||||
|
||||
```ts
|
||||
import { saveBreakPoint, getBreakPoint } from '@/utils/yiban';
|
||||
|
||||
// 保存播放断点
|
||||
await saveBreakPoint({
|
||||
userId: '123456',
|
||||
courseId: '789',
|
||||
lessonId: '001',
|
||||
breakPoint: 120, // 秒
|
||||
});
|
||||
|
||||
// 获取播放断点
|
||||
const breakpoint = await getBreakPoint({
|
||||
userId: '123456',
|
||||
courseId: '789',
|
||||
lessonId: '001',
|
||||
});
|
||||
```
|
||||
|
||||
#### 4. 用户答题记录
|
||||
|
||||
```ts
|
||||
import { saveUserAnswer } from '@/utils/yiban';
|
||||
|
||||
// 保存答题记录
|
||||
await saveUserAnswer({
|
||||
userId: '123456',
|
||||
lessonId: '001',
|
||||
courseId: '789',
|
||||
questionOrder: 1,
|
||||
answer: 'A',
|
||||
});
|
||||
```
|
||||
|
||||
#### 5. 用户状态管理
|
||||
|
||||
```ts
|
||||
import { useUserStore } from '@/stores';
|
||||
|
||||
function MyComponent() {
|
||||
const { userId, userName, setUserInfo, setYibanConnectionStatus } = useUserStore();
|
||||
|
||||
// 设置易班连接状态
|
||||
setYibanConnectionStatus('connected');
|
||||
|
||||
// 设置用户信息
|
||||
setUserInfo({
|
||||
userId: '123456',
|
||||
userName: '张三',
|
||||
userAvatar: 'https://...'
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
### 移动端调试
|
||||
|
||||
开发环境自动启用 vconsole,可在移动端查看:
|
||||
- Console 日志
|
||||
- Network 请求
|
||||
- Element 结构
|
||||
- Storage 存储
|
||||
|
||||
### 课程画布适配
|
||||
|
||||
模板采用 [src/app.config.ts](src/app.config.ts) 中的 `appConfig.design` 作为课程设计稿尺寸,默认是 `1920 x 1080`。页面内容按该设计稿开发,App 外层会通过整体缩放适配不同屏幕。
|
||||
|
||||
当前默认缩放策略:
|
||||
|
||||
- PC 端:按可视区域等比缩放并居中显示
|
||||
- 大屏:`appConfig.scale.max` 默认为 `1`,不会超过设计稿原始尺寸,周围留白
|
||||
- 移动端:优先横屏访问,竖屏时显示横屏提示
|
||||
- 视口:缩放逻辑优先读取 `visualViewport`,移动端地址栏显示/隐藏时更稳定
|
||||
- 页面内容:按 `1920 x 1080` 设计稿进行开发,不使用 rem 适配
|
||||
|
||||
整体缩放逻辑维护在 [src/utils/useScale.ts](src/utils/useScale.ts)。如需修改设计稿尺寸或最大放大比例,优先修改 [src/app.config.ts](src/app.config.ts)。
|
||||
|
||||
本地运行 `bun dev` 后,可以访问标准课程页示例:
|
||||
|
||||
```text
|
||||
http://localhost:5173/#/course-demo
|
||||
```
|
||||
|
||||
`CourseDemo` 用于展示标准课程页面结构、易班 session fallback、Toast、Overlay 和 SpotlightGuide 的基础接入方式。
|
||||
|
||||
## 弹层基础组件
|
||||
|
||||
模板内置 `Portal` 和 `Overlay`,用于课程页面组合自定义弹窗、提示层、章节面板、全屏 loading 等弹层内容。
|
||||
|
||||
`Overlay` 已经内置 `Portal`,默认会挂载到 App 缩放画布内部,适合课程弹层跟随 `1920 x 1080` 画布一起缩放,并支持直接放入课程自己的切图和内容:
|
||||
|
||||
```tsx
|
||||
import { Overlay } from "@/components/common";
|
||||
|
||||
<Overlay
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
backgroundImage="dialog/overlay-bg.png"
|
||||
backgroundClassName="bg-cover bg-center"
|
||||
contentClassName="flex items-center justify-center"
|
||||
>
|
||||
<img src="/images/dialog.png" alt="课程提示" />
|
||||
</Overlay>;
|
||||
```
|
||||
|
||||
说明:
|
||||
|
||||
- `backgroundImage`: 传入 `src/assets/images` 下的图片路径,组件内部会通过 `getBackgroundImage` 处理。
|
||||
- `backgroundClassName`: 使用 Tailwind class 控制背景层样式,例如 `bg-cover`、`bg-center`、渐变、透明度等。
|
||||
- `contentClassName`: 控制内容层布局,弹窗视觉样式由具体课程页面自行决定。
|
||||
- `closeOnBackgroundClick`: 是否允许点击背景关闭,默认开启。
|
||||
- `closeOnEscape`: 是否允许按 Esc 关闭,默认开启。
|
||||
- `lockScroll`: 弹层打开时是否锁定页面滚动,默认开启。
|
||||
- `variant`: 提供 `dim` / `light` / `transparent` 三种基础背景。
|
||||
|
||||
### Portal 挂载位置
|
||||
|
||||
`Portal` 默认挂载到 `document.body`,`Overlay` 默认挂载到 App 缩放画布内部。如果 `Portal` 也需要跟随模板的 `1920 x 1080` 课程画布一起缩放,可以使用 `placement="app"`:
|
||||
|
||||
```tsx
|
||||
<Overlay placement="app" open={open} onClose={() => setOpen(false)}>
|
||||
{/* 和课程画布一起缩放的弹层 */}
|
||||
</Overlay>
|
||||
```
|
||||
|
||||
如果需要挂载到业务自己的容器,可以传入 `container`。`container` 支持 DOM 元素、React ref 或返回元素的函数:
|
||||
|
||||
```tsx
|
||||
import { useRef } from "react";
|
||||
import { Overlay } from "@/components/common";
|
||||
|
||||
const rootRef = useRef<HTMLDivElement>(null);
|
||||
|
||||
<div ref={rootRef} className="relative" />;
|
||||
|
||||
<Overlay
|
||||
container={rootRef}
|
||||
className="absolute"
|
||||
open={open}
|
||||
onClose={() => setOpen(false)}
|
||||
>
|
||||
{/* 挂到自定义容器里的弹层 */}
|
||||
</Overlay>;
|
||||
```
|
||||
|
||||
挂载优先级:`container` > `placement` > 组件默认值。`Portal` 默认 `placement="body"`,`Overlay` 默认 `placement="app"`。如只需要改变渲染位置,也可以单独使用 `Portal`。
|
||||
|
||||
## Toast 轻提示
|
||||
|
||||
模板内置 `ToastProvider`、`ToastViewport` 和 `useToast`,用于保存成功、提交失败、网络异常等轻量反馈。
|
||||
|
||||
`App` 已默认接入 `ToastProvider` 和 `ToastViewport`,页面组件中可以直接使用:
|
||||
|
||||
```tsx
|
||||
import { useToast } from "@/components/common";
|
||||
|
||||
const toast = useToast();
|
||||
|
||||
toast.success("保存成功");
|
||||
toast.error("网络异常,请稍后重试");
|
||||
```
|
||||
|
||||
支持:
|
||||
|
||||
- `toast.info(message)`
|
||||
- `toast.success(message)`
|
||||
- `toast.warning(message)`
|
||||
- `toast.error(message)`
|
||||
- `toast.show({ message, type, title, duration, className, data })`
|
||||
|
||||
如果课程视觉风格不同,可以自定义 `ToastViewport`:
|
||||
|
||||
```tsx
|
||||
<ToastViewport
|
||||
classNames={{
|
||||
item: "rounded-full border-0 bg-black/80 px-8 py-4 text-white",
|
||||
title: "hidden",
|
||||
message: "text-white",
|
||||
close: "text-white/70",
|
||||
}}
|
||||
/>
|
||||
```
|
||||
|
||||
也可以完全接管单条 Toast 渲染:
|
||||
|
||||
```tsx
|
||||
<ToastViewport
|
||||
renderToast={(toast, { remove }) => (
|
||||
<div className="pointer-events-auto rounded-full bg-black/80 px-8 py-4 text-white">
|
||||
<span>{toast.message}</span>
|
||||
<button onClick={() => remove(toast.id)}>关闭</button>
|
||||
</div>
|
||||
)}
|
||||
/>
|
||||
```
|
||||
|
||||
本地运行 `bun dev` 后,可以访问 `/#/components` 查看 Toast 示例。
|
||||
|
||||
## 拖拽交互
|
||||
|
||||
模板引入 dnd-kit 作为拖拽基础能力,适合网络课程中常见的拖物品到目标区、分类、匹配、排序等交互。
|
||||
|
||||
已封装基础组件:
|
||||
|
||||
- `DragDropProvider`: 拖拽上下文,默认启用 Pointer / Touch / Keyboard sensors。
|
||||
- `Draggable`: 可拖拽元素。
|
||||
- `Droppable`: 可投放区域。
|
||||
|
||||
基础示例:
|
||||
|
||||
```tsx
|
||||
import { DragDropProvider, Draggable, Droppable } from "@/components/business";
|
||||
import { useScale } from "@/utils";
|
||||
|
||||
const scale = useScale();
|
||||
|
||||
<DragDropProvider
|
||||
scale={scale}
|
||||
onDragEnd={(event) => console.log(event.active.id, event.over?.id)}
|
||||
>
|
||||
<Draggable id="apple">苹果</Draggable>
|
||||
<Droppable id="fruit-zone">水果区域</Droppable>
|
||||
</DragDropProvider>;
|
||||
```
|
||||
|
||||
由于模板整体使用 `transform: scale(...)` 缩放课程画布,拖拽内容在画布内时建议给 `DragDropProvider` 传入当前 `scale`,避免拖拽元素和鼠标/手指移动不同步。
|
||||
|
||||
`DragDropProvider` 默认会根据 `scale` 修正拖拽启动距离和拖拽位移,并使用 `pointerWithin` 优先、`closestCenter` 兜底的碰撞检测策略,让“拖到目标区域”类课程交互更符合手指/鼠标位置直觉。
|
||||
|
||||
本地运行 `bun dev` 后,可以访问 `/#/components` 查看拖拽示例。
|
||||
|
||||
> 当前基础封装优先覆盖多端拖拽和投放区域判断。排序、分类、拼图等更上层课程交互可以继续基于这些组件封装。
|
||||
|
||||
## 引导聚光灯
|
||||
|
||||
模板内置 `SpotlightGuide` 引导组件,适合课程首次学习时突出关键操作区域。
|
||||
|
||||
### 基础使用
|
||||
|
||||
在页面元素上添加 `data-guide`:
|
||||
|
||||
```tsx
|
||||
<Button data-guide="start-button">开始学习</Button>
|
||||
```
|
||||
|
||||
在页面初始化时启动引导:
|
||||
|
||||
```tsx
|
||||
import { useEffect } from "react";
|
||||
import { SpotlightGuide } from "@/components/common";
|
||||
import { useGuideStore } from "@/stores";
|
||||
|
||||
export default function LessonPage() {
|
||||
useEffect(() => {
|
||||
useGuideStore.getState().startGuide({
|
||||
courseId: "lesson-1",
|
||||
guideId: "intro",
|
||||
steps: [
|
||||
{
|
||||
id: "start",
|
||||
target: { dataGuide: "start-button" },
|
||||
title: "开始学习",
|
||||
description: "点击这里开始本节课程。",
|
||||
placement: "bottom",
|
||||
},
|
||||
],
|
||||
});
|
||||
}, []);
|
||||
|
||||
return <SpotlightGuide />;
|
||||
}
|
||||
```
|
||||
|
||||
### 持久化说明
|
||||
|
||||
引导状态接入 Zustand,并通过 Zustand `persist` 只持久化已完成记录:
|
||||
|
||||
```ts
|
||||
completedGuideMap: {
|
||||
"lesson-1:intro": true,
|
||||
}
|
||||
```
|
||||
|
||||
默认同一个 `courseId + guideId` 只显示一次。点击“完成”或“跳过”都会标记为已完成,后续不会自动显示。
|
||||
|
||||
如需重新显示:
|
||||
|
||||
```ts
|
||||
useGuideStore.getState().resetGuide("lesson-1", "intro");
|
||||
```
|
||||
|
||||
### Step 配置
|
||||
|
||||
```ts
|
||||
{
|
||||
id: "start",
|
||||
target: { dataGuide: "start-button" },
|
||||
title: "开始学习",
|
||||
description: "点击这里开始本节课程。",
|
||||
placement: "bottom",
|
||||
allowTargetClick: true,
|
||||
}
|
||||
```
|
||||
|
||||
支持:
|
||||
|
||||
- `target`: CSS selector 或 `{ dataGuide: "xxx" }`
|
||||
- `placement`: `top` / `bottom` / `left` / `right` / `auto`
|
||||
- `allowTargetClick`: 是否允许点击高亮目标
|
||||
- `padding` / `radius`: 调整高亮区域
|
||||
- `panelClassName`: 针对单步自定义提示框样式
|
||||
|
||||
> 建议 `data-guide` 只使用字母、数字、横线和下划线,例如 `start-button`、`question_1`。
|
||||
|
||||
### 高级交互说明
|
||||
|
||||
`allowTargetClick` 只负责让高亮区域下方的真实元素可以被点击,不会自动切换引导步骤。
|
||||
|
||||
如果目标元素点击后需要进入下一步,需要在业务点击逻辑中手动调用 `nextStep`、`finishGuide` 或 `closeGuide`:
|
||||
|
||||
```tsx
|
||||
const { nextStep } = useGuideStore();
|
||||
|
||||
<Button
|
||||
data-guide="play-button"
|
||||
onClick={() => {
|
||||
playVideo();
|
||||
nextStep();
|
||||
}}
|
||||
>
|
||||
播放
|
||||
</Button>
|
||||
```
|
||||
|
||||
### 样式与层级
|
||||
|
||||
`SpotlightGuide` 默认通过 Portal 挂载到 `document.body`,可以正确适配整体缩放后的坐标。
|
||||
|
||||
如遇到课程弹窗、横屏提示等全局层级冲突,可以通过 `theme.zIndex` 调整:
|
||||
|
||||
```tsx
|
||||
<SpotlightGuide theme={{ zIndex: 1200 }} />
|
||||
```
|
||||
|
||||
开发环境中,如果目标元素不存在,页面会显示开发提示面板,方便检查 `data-guide` 或 selector;生产环境默认会自动跳过找不到目标的步骤。
|
||||
|
||||
组件内置了遮罩淡入、高亮呼吸和提示框入场动画,并兼容系统的 `prefers-reduced-motion` 设置。
|
||||
|
||||
## 路由懒加载
|
||||
|
||||
模板内置了 `lazyRoute` 工具函数,新页面可以这样配置:
|
||||
@@ -75,7 +595,7 @@ src/
|
||||
```tsx
|
||||
{
|
||||
path: "about",
|
||||
lazy: lazyRoute(() => import("../pages/About/About")),
|
||||
lazy: lazyRoute(() => import("../pages/About")),
|
||||
}
|
||||
```
|
||||
|
||||
|
||||
Reference in new issue
Block a user