4、目录结构设计:分层架构思想、src目录规划、公共模块与业务模块分离
聊到目录结构,我见过太多项目一开始随便建几个文件夹就开干。结果呢?三个月后,连自己写的代码放哪儿都找不着了。说白了,目录结构就是项目的骨架。骨架歪了,后面再怎么填肉都别扭。
这一章,咱们就聊聊怎么搭一个经得起折腾的目录结构。我会结合自己踩过的坑,给你一套可复用的方案。
4.1 分层架构思想:别把所有代码塞一层
先问个问题:为什么需要分层?
我刚开始做项目时,习惯把所有逻辑都写在组件里。按钮点击、数据请求、状态管理、UI渲染,全揉在一起。结果呢?改一个需求,要翻遍整个文件。后来我学乖了——分层。
分层架构的核心就一句话:各司其职,互不干扰。每一层只关心自己的事,不越界。
拿前端项目来说,我一般分三层:
| 层级 | 职责 | 典型内容 |
|---|---|---|
| 展示层 | 负责UI渲染、用户交互 | 组件、页面、布局 |
| 业务层 | 处理业务逻辑、状态管理 | Store、Service、Hooks |
| 基础设施层 | 提供通用能力、工具函数 | API封装、工具库、配置 |
你想想看,如果哪天要换UI框架,只需要动展示层。业务逻辑和API调用完全不受影响。这就是分层带来的好处。
4.2 src目录规划:从混乱到有序
有了分层思想,接下来就是落地。我见过很多项目的src目录长这样:
src/
components/
pages/
utils/
services/
...
看着还行?但项目一大了,components里会有几百个文件,找起来想哭。我个人习惯的规划方式是这样的:
src/
├── api/ # API接口层
│ ├── modules/ # 按业务模块拆分
│ └── request.js # 请求实例封装
├── assets/ # 静态资源
│ ├── images/
│ ├── styles/
│ └── fonts/
├── components/ # 公共组件
│ ├── base/ # 基础组件(按钮、输入框等)
│ └── business/ # 业务组件(用户卡片、订单列表等)
├── composables/ # 组合式函数(Vue3)或 Hooks(React)
├── layouts/ # 布局组件
├── pages/ # 页面级组件
├── router/ # 路由配置
├── store/ # 状态管理
├── utils/ # 工具函数
└── config/ # 项目配置
嗯,这里要注意:不要为了分层而分层。如果你的项目只有几个页面,搞这么复杂反而累赘。我一般在项目启动时就按这个模板搭好,后续按需增减。
4.3 公共模块与业务模块分离
这是很多团队容易忽略的点。公共模块和业务模块混在一起,后果就是:复用性差,耦合度高。
怎么区分?我有个简单的判断标准:
- 公共模块:不依赖具体业务,换个项目也能用。比如按钮组件、日期选择器、请求封装。
- 业务模块:跟当前业务强相关,换个场景就得改。比如订单列表组件、用户信息卡片。
来看个实际例子。假设我们有个电商项目:
src/
components/
base/ # 公共模块
Button.vue
Input.vue
Modal.vue
Pagination.vue
business/ # 业务模块
ProductCard.vue # 商品卡片
CartItem.vue # 购物车项
OrderList.vue # 订单列表
公共模块的组件,我一般会做到无状态、可配置。通过props控制行为,不依赖任何业务数据。业务模块则相反,它可以直接使用store里的数据。
为什么会这样?我举个例子。你写了个公共的Table组件,结果里面硬编码了「删除订单」的逻辑。下次另一个项目要用这个Table,还得把这段逻辑删掉。说白了,公共模块一旦耦合了业务,就不再「公共」了。
4.4 避坑指南:我踩过的那些坑
做目录结构设计,有几个坑我反复踩过,分享给你:
- 层级太深:有人喜欢把文件夹套五六层,比如
src/components/business/order/list/item。找文件得点半天。我一般控制在三层以内。 - 命名混乱:同一个功能,有人叫
userService,有人叫UserApi,还有人叫user.js。团队里得统一命名规范。 - 循环引用:A模块引用了B模块,B模块又引用了A模块。这种问题在目录结构混乱时特别容易出现。
- 过度抽象:为了「复用」而强行抽公共模块,结果抽出来的东西没人用。我建议等出现三次重复代码时再考虑抽象。
4.5 小结
目录结构设计没有标准答案,但有通用原则。分层架构让代码职责清晰,src目录规划让项目有序,公共与业务分离让复用成为可能。你想想看,一个好的目录结构,是不是比写一堆注释管用多了?
下一章,咱们聊聊组件设计原则。到时候我会分享一些更具体的实战技巧。