- 作者:老汪软件技巧
- 发表时间:2024-09-28 15:02
- 浏览量:
为确保React项目开发的代码质量、提升团队协作效率、便于后期维护,以过去的经验总结了一篇react开发的基本规范。本规范旨在提供一套清晰、统一的代码编写标准,涵盖了代码风格、命名规范、组件设计等多个方面。希望对正在进行React项目开发的朋友们提供一些有用的参考和帮助。
本示例展示一个基于vite搭建的react项目:
├── .vscode # vscode插件配置
├── dist # 打包输出目录
├── public # 项目公共资源
├── src # src源代码目录
│ ├── assets # 静态资源
│ ├── components # 公共组件
│ ├── constants # 公共常量
│ ├── hooks # 全局hook
│ ├── layouts # 全局布局组件
│ ├── pages # 页面内容
│ ├── routes # 路由服务
│ ├── services # 接口服务
│ ├── stores # 全局共享状态
│ ├── styles # 全局样式
│ ├── types # 全局类型
│ ├── utils # 公共方法
│ ├── App.tsx # App根组件
│ ├── main.tsx # 入口文件
├── .editorconfig # 编辑器配置
├── .env.development # 开发环境变量
├── .env.production # 生产环境变量
├── .env.testing # 测试环境变量
├── .eslintignore # eslint忽略配置
├── .eslintrc.cjs # eslint代码校验配置
├── .gitattributes # git忽略配置
├── .gitignore # git配置
├── .prettierignore # prettierignore忽略配置
├── .prettierrc # prettierrc代码风格配置
├── .yarnrc # yarn镜像配置
├── README.md # 说明文件
├── index.html # index.html
├── package.json # 依赖包配置
├── tsconfig.json # typescript配置
├── vite.config.ts # vite构建配置
└── yarn.lock
一,目录规范
关于目录规范,我们主要关注src目录下面的内容规范。
1,components目录规范
components目录存放整个项目的公共组件:
├── components # 公共组件
│ └── MyCom1 # 大驼峰命名
│ ├── index.tsx # 组件文件
│ └── MyCom2
│ ├── Other.tsx # 子组件文件(可选),大驼峰命名
│ ├── index.tsx # 组件文件
│ ├── index.css # 样式文件
│ ├── type.ts # 类型文件
│ └── ...
2,constants目录规范
constants目录存放整个项目的公共常量:
├── constants # 全局常量目录,按照不同的内容划分为单独的文件
│ ├── index.ts
│ ├── config.ts
│ ├── ...
3,hooks目录规范
hooks目录存放整个项目的公共hook:
├── hooks # 公共hook
│ ├── useApp.ts # 封装的hook必须以use开头 (小驼峰命名)
│ ├── useEchart.ts
│ ├── useUserInfo.ts
│ ├── ...
4,pages目录规范
pages目录存放整个项目的页面开发内容:
├── pages # 页面路由组件内容
│ └── login # 简单的页面组件
│ ├── index.tsx # 组件文件
│ └── home # 复杂的页面组件
│ ├── components # 存储本页面相关的功能组件
│ │ ├── HeaderInfo # 复杂的功能组件需要收拢到一个文件夹中 (大驼峰命名)
│ │ ├── OtherComponent.tsx # 本组件中可能存在的其他子组件文件 (大驼峰命名)
│ │ ├── index.tsx
│ │ ├── index.css
│ │ ├── type.ts
│ │ ├── AddModal.tsx # 简单的功能组件可以直接以一个单独的文件存在 (大驼峰命名)
│ │ ├── DeleteModal.tsx
│ │ ├── ...
│ ├── detail.tsx # 详情页面入口文件 (可选)
│ ├── index.tsx # 路由组件入口文件
│ ├── index.css # 样式文件
│ ├── type.ts # 类型文件
│ └── ...
页面级别路由组件应该始终创建有独立的文件夹(小驼峰命名)。
5,services目录规范
services目录存放整个项目的接口服务:
├── services # 接口服务,按照不同的模块分为单独的文件
│ ├── app.ts # 应用级的接口
│ ├── user.ts # 用户相关的接口
│ ├── menu.ts # 其他按照页面内容进行划分模块
│ ├── ...
6,stores目录规范
stores目录存放整个项目的公共状态:
├── stores # 公共状态,按照不同的模块划分为单独的文件
│ ├── app.ts # 应用级的全局状态,配置状态
│ ├── user.ts # 用户相关的全局状态,比如登录状态,用户信息,权限信息
│ ├── ...
7,types目录规范
types目录存放与services目录对应的接口类型:
├── types # 接口的类型定义文件,与services目录下的模块一一对应
│ ├── app.d.ts # 应用级的接口类型定义
│ ├── user.d.ts # 用户相关的接口类型定义
│ ├── menu.d.ts # 其他按照页面内容进行划分模块
│ ├── common.ts # 推荐额外创建一个【common.ts】存储全局通用的类型定义
│ ├── ...
8,utils目录规范
utils目录存放整个项目的公共方法:
├── utils # 全局公共方法
│ ├── index.ts
│ ├── axios.ts
│ ├── echarts.ts
│ ├── ...
二,命名规范1,组件命名路由组件
├── pages # 路由组件
│ └── home # 路由组件目录 (小驼峰命名)
│ ├── detail.tsx # 详情页面入口文件 (可选)
│ ├── index.tsx # 页面路由组件入口 (小驼峰命名)
│ ├── index.css # 样式文件 (小驼峰命名)
│ ├── type.ts # 类型文件 (小驼峰命名)
│ └── ...
功能组件
├── components # 功能组件
│ ├── HeaderInfo # 复杂的功能组件需要收拢到一个文件夹中 (大驼峰命名)
│ ├── Other.tsx # 本组件中可能存在的其他子组件文件 (大驼峰命名)
│ ├── index.tsx # 组件文件 (小驼峰命名)
│ ├── index.less # 样式文件 (小驼峰命名)
│ ├── type.ts # 类型文件 (小驼峰命名)
│ ├── AddModal.tsx # 简单的功能组件可以直接以一个单独的文件存在 (大驼峰命名)
│ ├── DeleteModal.tsx
│ ├── ...
弹窗类组件
# 弹窗类组件以Modal或者Drawer结尾命名
├── components
│ ├── AddModal # 复杂的功能组件需要收拢到一个文件夹中 (大驼峰命名)
│ ├── index.tsx
│ ├── index.less
│ ├── type.ts
│ ├── AddModal.tsx
2,编码命名
在平时的项目开发中尽量遵循以下命名规范:
组件命名
// AddModal.tsx
// 组件命名与文件命名保持统一
const AddModal = () => {}
export default AddModal;
变量命名
// 小驼峰命名
const tableRef = useRef()
const [count, setCount] = useState()
常量命名
// constants目录中的全局常量:推荐全大写命名,多单词下划线连接
export const IS_PRODUCTION = true
export const STATE_ENUM = new Map()
函数命名
// 一般的处理函数推荐使用 handle + action 命名
const handleClick = () => {}
const handleChange = () => {}
const handleAdd = () => {}
const handleDelete = () => {}
// 或者使用on + action命名
const onClick = () => {}
// 对于返回布尔值的方法,推荐使用 is/has为前缀
const isEmpty = () => {}
const hasChildren = () => {}
// 对于一些其他的方法:整体上上应该遵循(动词 + 名词)的命名
...
三,组件规范
一个react组件可以划分为如下的几个基本区域:
const Index = (props) => {
// 1.变量区域:初始化定义组件所需的变量或者常量
const { title, type } = props; // 组件的props应当始终在首行直接解构使用
const tableRef = useRef();
const [count, setCount] = useState();
...
// 2.请求区域:可以使用ahook的useRequest初始化请求 (可选)
const { data = [] } = useRequest( async () => {
const res = await getInfo();
return res.data;
})
// 3.方法区域:定义组件中使用到的方法
const handleClick = () => {}
// 4.栏目区域:columns定义
const columns = []
// 5.副作用区域:组件的各种副作用操作
useEffect(()=> {
...
}, [])
// 6.渲染区域:组件render的渲染内容
return ...
}
注意: 开发时遵循组件单一原则,一个.jsx/tsx文件始终应该只定义一个组件。
四,TypeScript规范1,组件类型
所有react函数组件都可以直接使用React.FC进行类型注解。
// 组件类型
const Index: React.FC = () => {}
2,props类型
组件的props类型应该直接定义在组件上方,然后以泛型传递给React.FC。
组件的props类型推荐使用type定义,并且命名固定为PropsType,因为一个tsx文件中应当只存在一个组件,且props的类型不需要共享,同时一个组件内应该只存在props的类型,其他的TS类型应该定义到一个独立的type.ts文件中。
// props类型
type PropsType = {
type: string;
}
const Index: React.FC<PropsType> = (props) => {}
export default Index;
3,hooks类型
const [count, setCount] = useState(0)
const [loading, setLoading] = useState(false)
...
// useState
const [list, setList] = useState<MenuItem[]>([])
...
// useRef
const divRef = useRef<HTMLDivElement>(null)
const tableRef = useRef<TableActionType>(null)
...
// useMemo
const data = useMemo(()=> {...}, [])
4,方法类型
// 参数类型
const handleClick = (e: React.MouseEvent ) => {}
const handleClick = (id: number, name: string, record: Record ) => {}
// 抽离为独立的TS类型,定义在同级别的type.ts文件中
type FnType = (id: number, name: string, record: Record, ... ) => void
const handleClick: FnType = (id, name, record, ...) => {}
5,接口类型
对于services目录下的API接口我们应该添加它们的类型定义:
当然我们应该先在types中定义类型:
// types/user.d.ts
/**
* 用户相关的接口类型定义
*/
// 这里的命名空间,可以直接使用模块的全大写命名USER,或者大驼峰命名,使用Api为后缀的UserApi等都可以
declare namespace USER {
// 登录接口参数类型
interface LoginParams {
username: string;
password: string;
...
}
// 登录接口响应类型
interface LoginInfo {
name: string;
avatar: string;
userid: string;
...
}
}
然后在对应的接口中使用类型:
// services/user.ts
import request from "@/utils/request";
// 登录
export function login(data: USER.LoginParams) {
return request.post<USER.LoginInfo>("/api/admin/login", data);
}
6,类型文件
除了上述的类型,组件内部有时需要定义自己的类型,应该遵循就近原则,在组件同级创建type.ts文件,存储局部的TS类型。
├── pages
│ └── login
│ ├── index.tsx
│ ├── type.ts # 路由组件的类型文件
│ └── home
│ ├── components
│ │ ├── HeaderInfo
│ │ ├── OtherComponent.tsx
│ │ ├── index.tsx
│ │ ├── index.less
│ │ ├── type.ts # 功能组件的类型文件
│ │ ├── ...
│ ├── detail.tsx
│ ├── index.tsx
│ ├── index.css
│ ├── type.ts # 路由组件的类型文件
│ └── ...
五,总结
本节内容,主要介绍了React项目开发中的一系列开发规范,旨在确保代码质量、提升团队协作效率并便于后期维护。后续有新的想法也会更新到文章内容,大家如果有更好的建议,也可以随时评论反馈。写作不易,如果觉得还不错的话,欢迎点赞收藏哦!