# 前端目录与代码放置规范 > 说明真实分层、目录职责和新增代码放置规则。 --- ## 适用范围 单包 Vite + React/Vue + TypeScript 项目。 --- ## src 根目录结构 ``` src/ ├── api/ # 业务接口入口,按领域拆文件并统一导出 ├── assets/ # 静态资源占位目录 ├── common/ # 站点级常量、配置、静态数据、共享类型 ├── components/ # 跨页面复用组件 ├── hooks/ # 跨页面复用的 Hooks (React) / Composables (Vue) ├── pages/ # 路由页面 ├── router/ # 路由配置 ├── styles/ # 全局样式入口 ├── utils/ # 通用工具 ├── App.tsx # 应用壳 (React 为 .tsx,Vue 为 .vue) └── main.ts # 启动入口 ``` 新增目录前先判断能否归入已有层级;不要为了单个文件再造一层。 --- ## 各层职责 ### `src/api` 用于集中管理接口方法,按业务域拆分,例如: - `api-user.ts` - `api-order.ts` - `api-product.ts` 约束: - 文件名统一使用 `api-*.ts` - 所有接口通过 `src/api/index.ts` 暴露 - 页面、组件、Hook 不直接拼 URL 或内联请求逻辑 ### `src/common` 放站点级共享数据和基础类型,不放页面局部常量。 典型内容: - `config.ts` - `constants.ts` - `enum.ts` - `site-data.ts` - `site-types.ts` 站点级常量、配置、枚举、共享类型优先放此处;可远程获取的数据优先通过 `api/` + 页面 Hooks 获取,不要堆积在 `common/`。 ### `src/components` 放多个页面都会复用的通用组件和布局组件。 典型示例: - `layout-shell.tsx` (React) / `layout-shell.vue` (Vue) - `nav-header.tsx` / `nav-header.vue` - `content-card.tsx` / `content-card.vue` - `loading-state.tsx` / `loading-state.vue` - `empty-state.tsx` / `empty-state.vue` - `modal-common.tsx` / `modal-common.vue` 约束: - 文件名统一使用小写横杠 - 只有跨页面复用的组件才放这里 - 某个页面特有的展示块,优先直接放该页面目录下,避免过早公共化 ### `src/hooks` 放跨页面复用的状态与异步逻辑。React 中称为 Hooks,Vue 中称为 Composables。 典型示例: - `use-promise-data.ts` - `use-form.ts` - `use-modal.ts` - `use-table.ts` 约束: - 文件名统一使用 `use-*.ts`(React Hooks 和 Vue Composables 均遵循此命名) - 负责复用逻辑,不负责路由结构和大块 UI 拼装 ### `src/pages` 页面层按路由语义组织,一个目录对应一个页面或页面组。 典型结构: ``` pages/ ├── home/index.tsx (或 index.vue) ├── list/index.tsx (或 index.vue) ├── list/detail/index.tsx (或 index.vue) ├── admin/index.tsx (或 index.vue) └── admin/components/admin-table.tsx (或 .vue) ``` 约束: - 路由页面入口统一使用 `index.tsx` (React) 或 `index.vue` (Vue) - 有明确子路由的页面,使用目录嵌套表达层级,例如 `list/detail/` - 页面目录名统一使用小写横杠,例如 `order-detail/` 而非 `orderDetail/` - 仅后台页面共享的组件,放在 `pages/admin/components/`,不要提到全局 `components/` - 如果未来某个页面出现多个私有组件、Hook、转换函数,可以在该页面目录下新增 `components/`、`hooks/`、`utils/` 子目录;尚未形成稳定模式前,不要预先创建空目录 ### `src/router` 集中声明路由和布局装配关系,例如通过 layout route 划分不同壳层。 ### `src/utils` 放纯工具函数和请求封装,不承载业务页面状态。 典型文件: - `request.ts` - `format.ts` - `storage.ts` - `validate.ts` 请求封装、通用工具函数优先放在此处,不要散落到页面或 `api-*` 文件中。 ### `src/styles` 全局样式入口和主题变量注入位置。 职责: - 导入设计变量包 CSS,如 `@your-design-system/tokens/css` - 全局基础样式、重置样式、通用动画 - 禁止在组件内重复引入设计变量 CSS,统一从 `styles/` 入口注入 ### `src/assets` 静态资源占位目录。 职责: - 存放图片、字体、SVG 等静态文件 - 通过 Vite 自动处理路径引用,禁止手写相对路径拼接到 `public/` - 单个页面私有的静态资源,优先放在该页面目录下 --- ## 命名约定速查 | 类型 | 命名规则 | 示例 | 说明 | |---|---|---|---| | 接口文件 | `api-{domain}.ts` | `api-user.ts` | 按业务域拆分,统一从 `index.ts` 导出 | | Hook/Composable 文件 | `use-{feature}.ts` | `use-form.ts` | React Hooks / Vue Composables 通用命名 | | 组件文件 | 小写横杠 | `content-card.tsx` / `.vue` | 仅跨页面复用的组件 | | 页面入口 | `index.tsx` / `index.vue` | `pages/home/index.tsx` | 每个路由页面对应一个入口 | | 页面目录 | 小写横杠 | `order-detail/` | 有子路由时使用目录嵌套 | | 工具文件 | 小写横杠 | `format.ts` | 纯函数,不承载业务状态 | | 样式文件 | 小写横杠 | `index.css` | 全局样式入口 | --- ## 新增代码放置规则 ### 新增页面 - 新页面先放到 `src/pages//index.tsx` (React) 或 `index.vue` (Vue) - 有详情页或子页时,用子目录表达路由层级 - 页面只负责组装,不要把可复用块全部堆进页面入口文件 ### 新增共享组件 满足下面任一条件才放 `src/components/`: - 至少被两个页面复用 - 明显属于布局壳、空态、加载态、卡片、分页这类跨页面基础组件 否则放到对应页面目录下。 ### 新增接口 - 按业务域加到现有 `api-*.ts`,不要为单个接口新建零散文件 - 新增业务域时,才创建新的 `api-.ts` - 同步更新 `src/api/index.ts` ### 新增共享数据或类型 - 纯配置、导航、枚举、常量放 `src/common/` - 类型优先就近放到使用域;只有被多个页面共享时,才进入 `site-types.ts` 或拆新的共享类型文件 --- ## 反模式 - 把接口请求直接写进页面组件,绕过 `src/api/` - 把后台专用页面组件放进全局 `src/components/` - 为了“看起来规范”预先创建大量空的页面私有 `hooks/`、`utils/`、`components/` - 把路由层级和目录层级写反,例如把详情页和列表页并列平铺但路由嵌套 - 在 `common/` 堆放只给单页使用的常量或转换函数 --- ## 修改前检查 - 这段代码是路由页面、共享组件、共享 Hook/Composable、共享数据,还是接口定义? - 这个文件未来是否很可能被第二个页面复用? - 是否应该先并入现有业务域文件,而不是新造目录? - 是否和 `src/router/` 的路由分组保持一致?