目录规范
TIP
规定前端项目的目录结构与文件组织方式,适用于基于 Vue 3 + TypeScript + Vite 的业务应用与组件库项目。
设计原则
| 原则 | 说明 |
|---|---|
| 按职责分层 | 视图、逻辑、数据、配置分离,避免职责混杂 |
| 按功能聚合 | 业务模块内聚,相关页面、组件、接口放在同一模块下 |
| 浅层优先 | 目录层级不宜过深,建议不超过 4 层 |
| 命名一致 | 目录命名与 命名规范 保持一致 |
| 可迁移 | 模块可独立抽离,减少跨模块隐式依赖 |
目录结构
以下为推荐的项目根目录模板,可按实际规模裁剪或扩展。
typescript
project-root/
├── public/ # 静态资源(不经构建处理,原样拷贝)
│ └── favicon.ico
├── src/
│ ├── api/ # 接口层:按业务域划分
│ │ ├── admin/
│ │ │ ├── user.ts # 用户模块导出
│ │ │ └── role.ts # 角色模块导出
│ │ └── login/
│ ├── assets/ # 需构建处理的静态资源
│ │ ├── imgs/
│ │ └── fonts/
│ ├── styles/ # 全局样式(如全局变量、混入等)
│ │ ├── app.scss # 全局变量
│ │ ├── element-plus.scss # Element Plus 样式
│ │ ├── iconfont.scss # 图标字体样式
│ │ ├── main.scss # 主样式
│ │ ├── style.module.scss # 模块样式
│ │ ├── tooltip.scss # 提示样式
│ │ ├── variables.ts # 命名空间变量
│ │ └── index.scss # 样式入口
│ ├── components/ # 全局通用组件(跨模块复用)
│ │ └── GvAxios/
│ │ ├── index.vue
│ │ └── types.ts
│ ├── hook/ # 全局组合式函数
│ │ ├── service/ # 全局服务函数
│ │ └── web/ # 全局 Web 相关函数
│ ├── constants/ # 全局常量、枚举
│ │ └── index.ts
│ ├── directives/ # 全局自定义指令
│ ├── layouts/ # 布局组件
│ │ ├── Layout.vue
│ │ └── components/
│ │ └── GvAppMain.vue
│ ├── locales/ # 多语言资源(见多语言规范)
│ │ ├── zh-CN/
│ │ └── en/
│ ├── views/ # 业务模块(核心目录)
│ │ └──sysMng/
│ │ └── userMng/
│ │ ├── module/ # 页面级组件
│ │ │ ├── UserEdit.vue # 业务模块编辑组件
│ │ │ ├── helper.tsx # 配置工厂,用于生成表格、表单
│ │ │ └── types.d.ts # 类型定义
│ │ └── UserMngIndex.vue # 业务模块主页
│ ├── plugins/ # 第三方插件初始化
│ │ ├── elementPlus/
│ │ │ └── index.ts
│ │ ├── iconfont/
│ │ │ └── preload.ts
│ │ ├── svgIcon/
│ │ │ └── index.ts
│ │ ├── unocss/
│ │ │ └── index.ts/
│ │ └── i18n/
│ │ └── index.ts
│ ├── router/ # 路由入口
│ │ ├── index.ts
│ │ ├── helper.ts # 路由助手
│ │ └── routes.ts # 聚合各模块路由
│ ├── stores/ # 全局状态(Pinia)
│ │ ├── modules/
│ │ │ ├── app.ts
│ │ │ ├── locale.ts
│ │ │ ├── perms.ts
│ │ │ ├── tagsView.ts
│ │ │ └── user.ts
│ │ └── index.ts
│
│ ├── utils/ # 工具函数(无业务语义)
│ │ ├── format.ts
│ │ └── index.ts
│ ├── App.vue
│ └── main.ts # 应用入口
├── types/ # 全局类型声明
│ ├── app.d.ts
│ ├── global.d.ts
│ ├── env.d.ts
│ └── router.d.ts
├── tests/ # 测试(与 src 结构对应)
│ ├── unit/
│ └── e2e/
├── .env # 环境变量(不提交敏感信息)
├── .env.development
├── .env.production
├── index.html
├── vite.config.ts
├── tsconfig.json
└── package.json目录职责
src/api/ — 接口层
- 仅负责 HTTP 请求封装与类型定义,不包含 UI 逻辑
- 按系统服务分子目录,如
admin/、login/ - 每个子目录包含各功能模块的
user.ts(接口方法)
src/components/ — 全局组件
- 存放跨 2 个以上模块复用的组件
- 仅在一个模块内使用的组件,放在
modules/<name>中
src/views/ — 业务模块
- 按业务域划分,是页面开发的主要工作区
- 模块内文件仅被本模块或明确依赖方引用,避免模块间循环依赖
src/stores/ — 全局状态
- 跨页面、跨模块共享的状态放此处
- 模块私有状态优先使用
hook或模块内stores
src/utils/ vs src/hook/
| 目录 | 用途 | 示例 |
|---|---|---|
utils/ | 纯函数,无响应式、无生命周期 | formatDate、debounce |
hook/ | 含响应式逻辑、可组合 Vue API | useI18n、useUtil |
模块内目录
每个业务模块推荐采用统一结构,便于团队协作与 Code Review。
json
// 系统模块目录结构
views/
└── <manageName>/ # 系统模块名称
└── <moduleName>/ # 子模块名称
├── module/ # 子模块私有组件
└── moduleNameIndex.vue # 子模块主页
// 业务模块目录结构
views/
└── <serviceName>/ # 服务名称
└──<businessName>/ # 业务域名称
└──<featureName>/ # 功能名称
└── featureIndex.vue # 功能主页模块命名
目录使用 pascalCase 小驼峰结构,如 userMng、roleMng。
系统模块
- 页面组件 →
views/<manageName>/<moduleName>/,文件名与路由语义一致 - 功能主页 →
<moduleName>/<ModuleNameIndex>.vue - 详情等块 →
module/ - 接口调用 →
@/api/<serviceName>/<module.ts> - 类型定义 → 与使用方同目录的
module/types.ts,全局类型放types/app.d.ts - 样式 → 组件内
<style scoped lang="scss">优先;全局样式放assets/styles/ - 静态图片 → 模块专用图片需放模块目录;通用图片放
assets/imgs/
业务模块
- 页面组件 →
views/<serviceName>/<businessName>/<featureName>/,文件名与路由语义一致 - 功能主页 →
<featureName>/<FeatureNameIndex>.vue - 详情等块 →
<featureName>/ - 接口调用 →
@/api/<serviceName>/<feature.ts> - 类型定义 → 功能目录下
<featureName>/types.ts,全局类型放types/app.d.ts - 样式 → 组件内
<style scoped lang="scss">优先;全局样式放assets/styles/ - 静态图片 → 模块专用图片需放模块目录;通用图片放
assets/imgs/
❌ 反例:按文件类型扁平堆叠
typescript
src/
├── pages/ # 所有页面混在一起
├── apis/ # 所有接口混在一起
└── components/ # 所有组件混在一起,难以定位业务边界✅ 正例:按业务模块组织
typescript
src/
├── views/
│ ├── sysMng/
│ │ ├── userMng/
│ │ │ ├── module/
│ │ │ │ └── UserMngEdit.vue
│ │ │ └── UserMngIndex.vue
│ │ ├── roleMng/
│ │ │ └── RoleMngIndex.vue
│ │ └── ...
│ ├──svcProduct/
│ │ ├── svcLead/
│ │ │ ├── levelSetting/
│ │ │ │ ├── LevelSettingEdit.vue
│ │ │ │ ├── LevelSettingIndex.vue
│ │ │ │ └── ...
│ │ │ └── ...
│ │ └── ...
│ └── ...
└── components/ # 仅放真正全局通用的组件❌ 反例:层级过深
typescript
src / views / sysMng / userMng / module / list / components / form / fields / input / TextInput.vue;✅ 正例:控制层级,语义清晰
typescript
src/views/sysMng/userMng/
├── module/
│ └── UserMngEdit.vue
└── UserMngIndex.vue
src/views/svcProduct/svcLead/levelSetting/
├── LevelSettingEdit.vue
└── LevelSettingIndex.vue新增模块 Checklist
创建新业务模块时,按以下顺序初始化:
- 在
views/下创建业务模块目录及标准子目录, 如svcProduct/svcLead/levelSetting - 将目录结构添加到数据库做动态路由配置
- 在
api/下创建对应接口目录, 如svcProduct/levelSetting.ts - 补充
locales/多语言 key(如需要) - 确认无跨模块直接引用私有模块组件