# 组件创建规范 ## 目录结构 采用模块化结构组织组件: ``` src/components/ ├── video/ │ ├── index.ts # 导出入口 │ ├── video.tsx # 主组件 │ ├── video.types.ts # 类型定义 │ ├── video.hooks.ts # 组件专用 hooks(可选) │ └── video.utils.ts # 工具函数(可选) ├── button/ │ ├── index.ts │ └── button.tsx ├── ui/ # 基础 UI 组件 │ ├── button.tsx │ └── dialog.tsx └── index.ts # 统一导出所有组件 ``` ## 命名规范 | 类型 | 规范 | 示例 | | ---------- | ------------------ | ------------------ | | 文件名 | kebab-case | `video-player.tsx` | | 目录名 | kebab-case | `video-player/` | | 组件名 | PascalCase | `VideoPlayer` | | Props 接口 | `{组件名}Props` | `VideoPlayerProps` | | Ref 接口 | `{组件名}Ref` | `VideoPlayerRef` | | 导出类型 | `{组件名}{类型名}` | `VideoAnchor` | ## 文件结构顺序 每个组件文件按以下顺序组织: 1. **Imports** - 导入语句 2. **Types/Interfaces** - 类型定义(需导出) 3. **Constants** - 常量定义 4. **Helper Functions** - 辅助函数 5. **Component** - 组件定义 6. **displayName** - 设置显示名称 7. **Export** - 默认导出 ## 组件模板 ````tsx import React, { forwardRef, useRef, useState, useImperativeHandle, } from "react"; import { cn } from "@/lib/utils"; /** 组件配置项 */ export interface ComponentNameProps { /** 必填属性说明 */ requiredProp: string; /** 可选属性说明 */ optionalProp?: boolean; /** 子元素 */ children?: React.ReactNode; /** 自定义类名 */ className?: string; } /** 组件 Ref 暴露的方法 */ export interface ComponentNameRef { /** 方法说明 */ methodName: () => void; } /** * ComponentName - 组件简要说明 * * @example * ```tsx * * ``` */ const ComponentName = forwardRef( ({ requiredProp, optionalProp = false, className, children }, ref) => { // 状态定义 const [state, setState] = useState(""); // Ref 定义 const innerRef = useRef(null); // 暴露方法给父组件 useImperativeHandle(ref, () => ({ methodName: () => { // 实现 }, })); return
{children}
; } ); ComponentName.displayName = "ComponentName"; export default ComponentName; ```` ## index.ts 导出模板 ```ts export { default } from "./component-name"; export { default as ComponentName } from "./component-name"; export type { ComponentNameProps, ComponentNameRef } from "./component-name"; ``` ## 类型规范 - **必须**为所有 props、state、函数参数和返回值声明类型 - **禁止**使用 `any`,使用 `unknown` 或泛型替代 - **导出**所有公共接口和类型 - 使用 `React.ReactNode` 表示子元素类型 - 使用 `React.CSSProperties` 表示样式对象 ## 样式规范 - 使用 `cn()` 工具函数合并类名 - 优先使用 Tailwind CSS 类名 - 支持通过 `className` prop 自定义样式 - 避免内联样式,除非是动态计算值 ```tsx // ✅ 推荐
// ❌ 避免
``` ## 最佳实践 1. **单一职责** - 每个组件只做一件事,保持在 200 行以内 2. **使用 forwardRef** - 需要暴露 ref 的组件必须使用 3. **设置 displayName** - 便于 React DevTools 调试 4. **提取逻辑** - 复杂逻辑提取到自定义 hooks 5. **组合优于继承** - 使用 children 和 render props 6. **早返回** - 避免深层嵌套,使用 early return ## 文件拆分指南 | 文件 | 用途 | 何时创建 | | ---------------- | -------------- | -------------------- | | `*.tsx` | 主组件 | 必须 | | `*.types.ts` | 类型定义 | 类型超过 30 行 | | `*.hooks.ts` | 组件专用 hooks | 有可复用的状态逻辑 | | `*.utils.ts` | 工具函数 | 有纯函数逻辑需要提取 | | `*.constants.ts` | 常量定义 | 有多个常量需要共享 |