Pinia 总览:Vue 3 官方状态管理与 Vuex 对照

状态管理 目录里如果已经看过 Zustand,你会熟悉「小 API、少样板」这条路。
Vue 这边官方推的是 Pinia。这篇先把位置摆正:它是什么、和 Vuex 差在哪、什么时候该用全局 store,再谈怎么接到应用里。

可以把它理解成:

  • 每个 store 是一个 有 id 的响应式对象
  • 通过 defineStore 定义,在组件里用 组合式 API 风格 消费;
  • 不再强调 mutation 这一层(Vuex 4 虽兼容,但心智上 Pinia 更轻)。

和「只在组件里 ref/reactive」的差别:

  • 跨组件、跨路由 仍要共享的那部分领域状态,放进 store;
  • 只属于单个组件 UI 的临时状态,留在组件里更合适。

几条硬差异:

  • TypeScript 体验:Pinia 从设计上就更好推导类型,少一层 mutation 样板;
  • API 更贴近 Composition APIsetup store 可以自然复用 composable;
  • 模块不需要嵌套命名空间:多 store 用 id 区分,比 Vuex 模块树更直观;
  • DevTools 支持与官方维护节奏跟 Vue 3 一致。

Vuex 并没有立刻消失:

  • 老项目仍大量存在,维护时以官方迁移指南为准;
  • 新项目一般直接 Pinia,除非团队有强历史约束。

可以粗分三层:

  • 路由(Vue Router):URL 与导航状态、路由元信息;
  • Pinia:业务领域状态(用户、购物车、权限缓存);
  • 组件本地状态:展开收起、表单草稿、纯 UI。

避免:

  • 把「能由 URL 表达的状态」强塞进全局 store(刷新、分享链接会变难);
  • 把「只服务一个页面」的大块状态全局化(耦合和测试都会痛)。

轮廓步骤一般是:

  1. createPinia() 得到 pinia 实例;
  2. app.use(pinia) 挂到根应用;
  3. 各模块里 defineStore 定义 store;
  4. 组件中 useXxxStore() 取用。

SSR(Nuxt 等)场景要在框架文档里看 序列化与水合,和普通 SPA 略有不同,后面插件与持久化篇会再提一嘴边界。

  • Pinia 是 Vue 3 官方推荐的全局状态方案,心智比 Vuex 更轻;
  • 全局 vs 局部 的分工要先于 API 细节;
  • 下一篇从 state / getters / actions 把数据流走通。