本文从状态管理的设计原则出发,完整拆解 Pinia 在中大型项目中的工程化方案:目录结构、入口设计、模块化拆分、跨 store 调度、分级持久化、类型安全。附架构流程图与可直接落地的完整代码模板。前言很多团队上 Pinia 的姿势还停留在"每个页面写一个 store"的散兵游勇状态——模块拆分随意、持久化各写各的、跨模块调用混乱、类型声明缺失。项目一做大,状态管理反而成了新的技术债。Pinia 架构要解决的核心问题:模块化边界:按什么维度拆 store?拆多细?统一入口:如何注册、如何导出、如何保证单例?持久化策略:哪些存 localStorage?哪些存 sessionStorage?哪些只在内存?跨模块调度:store 之间互相调用怎么写才不耦合?类型安全:全链路 TS 类型推导怎么做?与请求层联动:loading、error、重试这些通用逻辑怎么收敛?本文给出一套可直接落地的中大型项目标准方案。一、状态管理的核心设计原则在动手写代码之前,先明确几条架构原则,这是所有设计的基石。1.1 单一职责原则(SRP)每个 store 只负责一个业务领域的状态,不混写。✅useUserStore:只管理用户信息、token、登录登出✅useAppStore:只管理全局 UI 状态(主题、侧边栏、语言)❌ 一个useCommonStore里塞了用户、菜单、字典、配置——典型的上帝对象1.2 领域驱动拆分(DDD 轻量化)按业务领域拆,不按页面拆。页面是临时的,领域是稳定的。领域模块职责生命周期user用户身份、权限、角色全局持久化app主题、布局、语言、全局 loading全局持久化(UI偏好)permission路由权限、按钮权限内存 + 会话级route标签页、面包屑、缓存路由会话级dict数据字典、枚举值内存 + 按需缓存业务模块(如 order / cart)各业务域状态按需,部分持久化1.3 Store 分层职责每个 store 内部严格分三层,不混写:state(数据层) → 只存数据,不写逻辑 getters(计算层) → 纯函数,派生状态,不修改数据 actions(行为层) → 唯一允许修改 state 的地方,承载业务逻辑虽然 Pinia 允许直接修改 state,但项目建议统一走 action 修改——不是技术限制,是工程规范。直接改的口子一开,三个月后你根本不知道 state 在哪被改的。1.4 持久化分级原则不是所有状态都要持久化。按数据特性分三级:级别存储介质适用数据示例L1 本地持久化localStorage跨会话保留的用户偏好主题、语言、tokenL2 会话级sessionStorage标签页内有效,关闭即清标签页状态、临时表单L3 内存级仅运行时刷新即重置权限列表、字典数据二、整体架构总览2.1 架构流程图按需引入应用入口 main.ts创建 Pinia 实例注册全局插件持久化 / 日志 / 重置统一导出入口 stores/index.tsuser 模块app 模块