状态目录结构应按业务域组织store模块,职责清晰、边界明确;状态层与服务层分离,API收口于services;类型定义独立,预留可扩展入口。

状态目录结构的关键是让每个模块职责清晰、边界明确,不和业务逻辑或视图耦合。重点不是“放得多”,而是“分得准”。
按业务域组织 store 模块
把状态按功能模块切分,而不是按技术类型堆在一起。比如用户相关状态全在 user.ts 里,订单相关全在 order.ts 中,避免出现一个 common.ts 扛下所有共享字段。
- 每个模块文件导出独立的 store(Pinia)或命名空间(Vuex),不混用
- 模块内只包含该业务域直接需要的状态、动作和 getter,不塞进跨域逻辑
- 模块名与 views、api、services 中对应目录保持一致,例如
src/views/user/↔src/store/modules/user.ts
拆分状态层与服务层
状态管理只负责“存什么、怎么读写”,不负责“从哪来”。API 请求统一收口到 src/services/,store 中通过调用 service 方法获取数据,而不是直接写 axios。
- store 模块中只引入对应的 service,例如
userStore只 importuserService - 异步操作统一用
async action封装,同步状态变更保持纯函数风格 - 避免在 store 里处理响应格式转换、错误弹窗等副作用逻辑
类型定义与状态分离
用 TypeScript 显式约束状态结构,类型文件不和 store 混放。建议单独建 src/types/store/ 或按模块配对,如 src/store/modules/user.types.ts。
立即学习“前端免费学习笔记(深入)”;
- state 接口、action 参数类型、返回类型都明确定义
- 不复用 view 层的接口(如
UserForm),状态层应有自己精简、稳定的类型 - 全局共享类型(如分页、响应体)放在
src/types/common.ts,避免重复声明
预留可扩展入口
初期可能只有一个 index.ts,但要为后续拆分留好路径。比如 Pinia 的主入口保持简洁,模块注册自动导入:
-
src/store/index.ts只做 createPinia() 和自动加载 modules - 新增业务模块时,只需在
modules/下加文件,无需改主入口 - 需要跨模块通信时,用 store 间调用或事件总线,不靠全局 state 堆砌


















