link,[object Object]
Skip to content

目录分层约定 ​

是什么 ​

「目录分层」回答的是:新文件放进 src 下的哪一格。放错格子的代价不是难看,是依赖方向会乱——今天 components 里偷偷调了个接口,明天所有组件都这么干,想换请求库就要翻遍全项目。

只需要记住一条核心纪律,其余都是它的推论:

核心纪律

依赖只能向下,UI 组件禁止直接调接口。

五个格子,各收什么 ​

目录收什么不收什么
views/(或 pages/)路由对应的一整个页面可复用的小组件(会被两个页面用的)
components/可复用的 UI 组件业务请求、全局状态的定义
composables/可复用的状态逻辑(useXxx)模板和样式
stores/全局状态(Pinia store)只在一个组件里用的状态
api/接口封装:一个端点一个函数组件名、样式类、任何和 UI 有关的东西

依赖方向 ​

views  →  components  →  composables  →  stores  →  api
   \                                                      ↑
    └────────────── 任何上层都可以用 api ──────────────────┘
  • 箭头右边永远不知道左边存在:api/user.ts 里 import 一个 .vue 文件,是分层已崩的明确信号
  • 「UI 组件禁止直接调接口」的推论:组件要数据,就让父层(view)或 composable 取好了传进去。这样接口一换,只有 api/ 和 views/ 要动,组件一个不用改

最小落地结构 ​

text
src/
├── api/            # user.ts → getUser(), login()……只有 fetch,没有状态
├── composables/    # useAuth.ts → 组合 api + 状态,暴露给组件
├── stores/         # auth.ts → 跨页面共享的登录态
├── components/     # UserCard.vue → 只吃 props,吐 emit
└── views/          # UserList.vue → 组装以上一切,路由直达

一个请求的正规路径:api/user.ts 定义函数 → composables/useUsers.ts 管加载态和缓存 → views/UserList.vue 调 composable → components/UserCard.vue 只收 props。每一层只认识下一层。

怎么选放哪

新文件犹豫时问一句:「它认识谁?」只认识数据 → api;管状态 → stores/composables;只管长相 → components;都认识 → views。

参考链接 ​