Pinia
Vue3 官方推荐的集中式状态管理方案及其设计边界。
#frame
#vue3
#concept
#growing
[!info] related notes
- 所属 MOC: Vue MOC
- 上位主题: Vue 3
- 依赖基础: Vue Composition API, Vue 响应式系统
- 相关问题: static-init-pinia-error
- 工程实践: pinia-store-design-patterns
- 通信选型: Vue 组件通信方式选择, Vue 通信方式对比
Pinia
Pinia 是 Vue3 生态中推荐的集中式状态管理库。它把跨组件共享状态,以及围绕这些状态的业务操作,从组件内部提炼到独立 store 中。 管理的是前端自己的状态。
一句话定义
Pinia 不是“把所有状态全局化”,而是给共享状态和业务动作一个稳定、可追踪、可复用的位置。
Pinia 解决什么问题
- 多个组件或页面需要共享同一份状态
- 状态变化来源太多,组件里已经难以追踪
- 请求、缓存、登录、权限等逻辑在多个地方重复出现
- 父子层层传值开始变得笨重
三个核心概念
state
表示事实本体,也就是 store 里真正持有的数据。
getters
表示派生结果,等价于 store 内部的 computed。
actions
表示业务动作,是修改状态和执行业务流程的主要入口。
最重要的边界
- 局部 UI 状态不要为了“统一”就塞进 Pinia
- 共享状态才值得进 store
- 派生结果优先用 getter,而不是额外再存一份 state
- 复杂业务流程尽量写在 action,组件保持薄一点
Setup Store 和 Option Store
- Option Store 更像传统配置结构,适合统一规范和常规业务
- Setup Store 更贴近 Composition API,适合逻辑复用和复杂组合
项目里最重要的不是“哪种更高级”,而是主风格统一。
storeToRefs() 为什么重要
解构 store 中的状态和 getter 时,应优先使用 storeToRefs(),避免直接解构后丢失响应式连接;action 则直接从 store 实例上取。
什么时候适合用 Pinia
- 用户信息、权限信息、主题配置
- 购物车、全局消息、跨页面筛选条件
- 需要被多个页面复用的列表查询状态
什么时候不适合用 Pinia
- 单个组件内部的弹窗开关、hover、局部表单态
- 只服务于一个页面且没有共享价值的临时状态
最短记忆方式
state:事实getters:对事实的解释actions:改变事实的方法
与 provide / inject 的边界
Pinia 本页只维护集中式共享状态模型。
如果问题是“props / emit / provide-inject / Pinia 应该怎么选”,统一看 Vue 组件通信方式选择;不要在 Pinia 本体重复维护另一份通信方式对比。
学习检查
不看正文回答:
- Pinia 为什么不是“把所有状态全局化”的工具?
- state、getter、action 分别代表事实、派生和动作中的哪一层?
- 为什么可推导值优先 getter/computed,而不是额外存一份 state?
- 直接解构 store 为什么可能失去响应式连接?
storeToRefs()解决什么? - 哪类局部 UI 状态不应该进入 Pinia?
- Server state 是否天然应该放 Pinia?判断时还要考虑哪些 ownership/freshness 问题?
- 如果需求只是祖先组件给深层后代提供上下文,为什么应先去 组件通信方式选择 判断?