You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
6.1 KiB
6.1 KiB
开发规范
文档版本:v1.1
最后更新:2025-01-18
目录
1. 文件命名规范
| 类型 | 命名规范 | 示例 |
|---|---|---|
| 组件文件 | PascalCase | StoryboardItem.tsx |
| Hook 文件 | camelCase | useStoryboards.ts |
| 工具文件 | camelCase | formatDuration.ts |
| 类型文件 | camelCase | storyboard.ts |
| 常量文件 | camelCase | routes.ts |
| 样式文件 | kebab-case | globals.css |
| 测试文件 | 原文件名.test | StoryboardItem.test.tsx |
2. 组件编写规范
2.1 组件文件结构
// 组件文件结构
import { useState, useCallback, memo } from 'react';
import { cn } from '@/lib/utils';
import { Button } from '@/components/ui/button';
import type { Storyboard } from '@types';
// Props 类型定义
interface StoryboardItemProps {
storyboard: Storyboard;
isSelected: boolean;
onSelect: (id: string) => void;
className?: string;
}
// 组件实现
export const StoryboardItem = memo(function StoryboardItem({
storyboard,
isSelected,
onSelect,
className,
}: StoryboardItemProps) {
// Hooks
const [isHovered, setIsHovered] = useState(false);
// 事件处理
const handleClick = useCallback(() => {
onSelect(storyboard.id);
}, [storyboard.id, onSelect]);
// 渲染
return (
<div
className={cn(
'p-3 rounded-md cursor-pointer transition-colors',
isSelected && 'bg-primary/10 border-l-2 border-primary',
isHovered && 'bg-muted',
className
)}
onClick={handleClick}
onMouseEnter={() => setIsHovered(true)}
onMouseLeave={() => setIsHovered(false)}
>
<h3 className="font-medium">{storyboard.title}</h3>
<p className="text-sm text-muted-foreground">{storyboard.description}</p>
</div>
);
});
2.2 组件编写原则
- 单一职责:每个组件只负责一个功能
- Props 类型化:所有 Props 必须定义类型
- 使用 memo:对于频繁渲染的组件使用 memo 优化
- 事件处理:使用 useCallback 缓存事件处理函数
- 样式管理:使用 cn 工具函数合并样式
3. 导入顺序规范
// 1. React 相关
import { useState, useEffect, useCallback } from "react";
// 2. 第三方库
import { useQuery } from "@tanstack/react-query";
import { z } from "zod";
// 3. 内部别名导入 - 组件
import { Button } from "@components/ui/button";
import { LoadingSpinner } from "@components/common";
// 4. 内部别名导入 - 其他
import { useStoryboards } from "@hooks/api/useStoryboards";
import { useEditorStore } from "@stores/editorStore";
import { cn } from "@/lib/utils";
// 5. 类型导入
import type { Storyboard } from "@types";
// 6. 相对路径导入
import { StoryboardItem } from "./StoryboardItem";
import "./StoryboardPanel.css";
4. Git Commit 规范
4.1 Commit 消息格式
<type>(<scope>): <subject>
<body>
<footer>
4.2 类型说明
| 类型 | 说明 | 示例 |
|---|---|---|
feat |
新功能 | feat(storyboard): 添加分镜拖拽排序 |
fix |
修复 | fix(timeline): 修复分镜看板缩放问题 |
docs |
文档 | docs(readme): 更新安装说明 |
style |
格式 | style(button): 调整按钮间距 |
refactor |
重构 | refactor(api): 重构 API 客户端 |
perf |
性能 | perf(list): 使用虚拟列表优化 |
test |
测试 | test(hooks): 添加 useDebounce 测试 |
chore |
构建/工具 | chore(deps): 升级依赖版本 |
4.3 Commit 示例
# 好的示例
feat(storyboard): 添加分镜拖拽排序功能
- 使用 dnd-kit 实现拖拽
- 支持跨分镜组拖拽
- 添加拖拽动画效果
Closes #123
# 不好的示例
update code
fix bug
5. 代码风格
5.1 TypeScript 规范
// ✅ 推荐:使用接口定义 Props
interface ButtonProps {
variant?: "primary" | "secondary";
size?: "sm" | "md" | "lg";
onClick?: () => void;
}
// ❌ 避免:使用 any
function handleData(data: any) {}
// ✅ 推荐:明确类型
function handleData(data: User) {}
// ✅ 推荐:使用可选链
const name = user?.profile?.name;
// ❌ 避免:多层判断
const name = user && user.profile && user.profile.name;
5.2 React 规范
// ✅ 推荐:使用函数组件
function Button({ children }: ButtonProps) {
return <button>{children}</button>;
}
// ❌ 避免:使用类组件(除非必要)
class Button extends React.Component { }
// ✅ 推荐:使用 Hooks
const [count, setCount] = useState(0);
// ✅ 推荐:提取自定义 Hook
function useCounter(initialValue: number) {
const [count, setCount] = useState(initialValue);
const increment = () => setCount(c => c + 1);
return { count, increment };
}
6. 注释规范
6.1 组件注释
/**
* 分镜项组件
*
* @param storyboard - 分镜数据
* @param isSelected - 是否选中
* @param onSelect - 选中回调
*/
export function StoryboardItem({
storyboard,
isSelected,
onSelect,
}: StoryboardItemProps) {
// ...
}
6.2 函数注释
/**
* 格式化时长
*
* @param seconds - 秒数
* @returns 格式化后的时长字符串 (mm:ss 或 hh:mm:ss)
*
* @example
* formatDuration(65) // "01:05"
* formatDuration(3661) // "01:01:01"
*/
export function formatDuration(seconds: number): string {
// ...
}
相关文档
最后更新:2025-01-18 | 版本:v1.1