4、目录结构设计:分层架构思想、src目录规划、公共模块与业务模块分离

聊到目录结构,我见过太多项目一开始随便建几个文件夹就开干。结果呢?三个月后,连自己写的代码放哪儿都找不着了。说白了,目录结构就是项目的骨架。骨架歪了,后面再怎么填肉都别扭。

这一章,咱们就聊聊怎么搭一个经得起折腾的目录结构。我会结合自己踩过的坑,给你一套可复用的方案。

4.1 分层架构思想:别把所有代码塞一层

先问个问题:为什么需要分层?

我刚开始做项目时,习惯把所有逻辑都写在组件里。按钮点击、数据请求、状态管理、UI渲染,全揉在一起。结果呢?改一个需求,要翻遍整个文件。后来我学乖了——分层。

分层架构的核心就一句话:各司其职,互不干扰。每一层只关心自己的事,不越界。

拿前端项目来说,我一般分三层:

层级 职责 典型内容
展示层 负责UI渲染、用户交互 组件、页面、布局
业务层 处理业务逻辑、状态管理 Store、Service、Hooks
基础设施层 提供通用能力、工具函数 API封装、工具库、配置

你想想看,如果哪天要换UI框架,只需要动展示层。业务逻辑和API调用完全不受影响。这就是分层带来的好处。

我的习惯:每层之间只通过接口通信,不直接引用内部实现。比如业务层只调用API层的接口函数,不直接操作axios实例。

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/           # 项目配置

嗯,这里要注意:不要为了分层而分层。如果你的项目只有几个页面,搞这么复杂反而累赘。我一般在项目启动时就按这个模板搭好,后续按需增减。

我曾经踩过的坑:把工具函数一股脑全塞进utils里,结果里面既有日期格式化,又有图片压缩,还有DOM操作。后来我按功能拆成 date.js、image.js、dom.js,找起来舒服多了。

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 避坑指南:我踩过的那些坑

做目录结构设计,有几个坑我反复踩过,分享给你:

  1. 层级太深:有人喜欢把文件夹套五六层,比如 src/components/business/order/list/item。找文件得点半天。我一般控制在三层以内。
  2. 命名混乱:同一个功能,有人叫 userService,有人叫 UserApi,还有人叫 user.js。团队里得统一命名规范。
  3. 循环引用:A模块引用了B模块,B模块又引用了A模块。这种问题在目录结构混乱时特别容易出现。
  4. 过度抽象:为了「复用」而强行抽公共模块,结果抽出来的东西没人用。我建议等出现三次重复代码时再考虑抽象。
我的小技巧:每次新建目录前,先问自己三个问题——这个文件属于哪一层?是公共还是业务?其他项目能不能直接用?想清楚了再动手。

4.5 小结

目录结构设计没有标准答案,但有通用原则。分层架构让代码职责清晰,src目录规划让项目有序,公共与业务分离让复用成为可能。你想想看,一个好的目录结构,是不是比写一堆注释管用多了?

下一章,咱们聊聊组件设计原则。到时候我会分享一些更具体的实战技巧。