Pinia 实战:模块化架构设计、统一调度与持久化方案全解

📅 2026/7/21 6:54:49 👁️ 阅读次数 📝 编程学习
Pinia 实战:模块化架构设计、统一调度与持久化方案全解

本文从状态管理的设计原则出发,完整拆解 Pinia 在中大型项目中的工程化方案:目录结构、入口设计、模块化拆分、跨 store 调度、分级持久化、类型安全。附架构流程图与可直接落地的完整代码模板。

前言

很多团队上 Pinia 的姿势还停留在"每个页面写一个 store"的散兵游勇状态——模块拆分随意、持久化各写各的、跨模块调用混乱、类型声明缺失。项目一做大,状态管理反而成了新的技术债。

Pinia 架构要解决的核心问题:

  1. 模块化边界:按什么维度拆 store?拆多细?
  2. 统一入口:如何注册、如何导出、如何保证单例?
  3. 持久化策略:哪些存 localStorage?哪些存 sessionStorage?哪些只在内存?
  4. 跨模块调度:store 之间互相调用怎么写才不耦合?
  5. 类型安全:全链路 TS 类型推导怎么做?
  6. 与请求层联动: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跨会话保留的用户偏好主题、语言、token
L2 会话级sessionStorage标签页内有效,关闭即清标签页状态、临时表单
L3 内存级仅运行时刷新即重置权限列表、字典数据

二、整体架构总览

2.1 架构流程图

按需引入

应用入口 main.ts

创建 Pinia 实例

注册全局插件
持久化 / 日志 / 重置

统一导出入口 stores/index.ts

user 模块

app 模块