Pinia
Vue3 官方推荐的集中式状态管理方案及其设计边界。
#tech / dev / frame
#resource / vue3
#type / concept
#status / growing
[!info] related notes
- 所属 MOC: Vue MOC
- 上位主题: vue3
- 依赖基础: Vue Composition API, Vue 响应式系统
- 相关问题: static-init-pinia-error
- 工程实践: pinia-store-design-patterns
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:改变事实的方法
面试要点
来自 pinia-vs-provide-inject-interview-question 的面试视角整理。
一句话回答
provide/inject 更适合祖先到后代之间共享上下文,Pinia 更适合被多个组件或页面复用、需要集中组织和追踪的业务级共享状态。
最稳的回答主线
provide/inject:跨层传上下文Pinia:共享状态、派生结果、业务动作集中管理- 如果只是组件树内部上下文,先别急着上全局 store
最短记忆方式
provide/inject 更像通道,Pinia 更像状态中心。