跳到主要内容

Vuex 与 Pinia 对比

这题不能只答“Pinia 更简单,Vuex 更老”。面试官更想听的是:

  • 两者设计哲学为什么不同
  • 在 Vue 2 / Vue 3、存量项目 / 新项目中怎么选
  • mutation、模块化、TypeScript、开发体验这些差异会带来什么实际影响

本文默认对比:

  • Vuex 3/4
  • Pinia 2/3 这一代设计思路

面试速答(30 秒版 TL;DR)

  • 两者都是 Vue 官方生态里的状态管理方案,但定位已经明显分化:
    • Vuex 更像传统集中式 Store 方案,适合历史项目和遗留生态
    • Pinia 是 Vue 官方现在推荐的新一代状态管理,API 更轻、更贴近 Composition API
  • 最大差异有四个:
    • Pinia 没有强制 mutation 层,改状态更直接
    • Pinia 以“多个 store”组织状态,比 Vuex 的模块树更自然
    • Pinia 的 TypeScript 推导明显更好
    • Pinia 对 Vue 3 组合式 API 更友好
  • 新项目通常优先 Pinia;老项目如果已经大量使用 Vuex,是否迁移看收益和成本。

先记对比主轴:Vuex = 单仓库 + 模块Pinia = 多 store + 更轻 API

一、先说结论:两者都能用,但推荐方向不同

1. Vuex 的定位

Vuex 在 Vue 2 时代几乎是标准答案,特点是:

  • 中心化
  • 约束明确
  • 调试链路清晰

它强调一套比较规整的结构:

  • state
  • getters
  • mutations
  • actions

2. Pinia 的定位

Pinia 是官方现在主推的方案,核心目标是:

  • 更少样板代码
  • 更自然的 TS 推导
  • 更贴近 Vue 3 的组合式写法

它不是“阉割版 Vuex”,而是对状态管理 API 的重新设计。

二、核心差异一:有没有 mutation

这是最常考的点。

1. Vuex:强调“提交 mutation”

Vuex 推荐链路是:

组件 -> dispatch/commit -> mutation/action -> state

例如:

store.commit('increment')

这样设计的好处是:

  • 状态变更入口统一
  • DevTools 更容易追踪每一步提交
  • 团队规范更强

但代价也明显:

  • 样板代码多
  • 小需求也要多写一层 mutation

2. Pinia:不再强制拆一层 mutation

Pinia 里通常直接在 action 中改状态:

increment() {
this.count++;
}

它的设计判断是:

  • mutationaction 在很多业务里过度分裂
  • 与其强制两层,不如保留更轻的约束

所以面试里最稳的说法是:

Pinia 并不是不能追踪状态变化,而是不再要求你必须通过 mutation 才算合法修改。

三、核心差异二:组织方式不同

1. Vuex 更像“一个总仓库 + 模块树”

常见写法是:

  • 根 store
  • 各业务模块 module
  • 通过 namespace 管理作用域

当项目大起来后,可能会出现:

  • 模块层级深
  • 命名空间字符串较多
  • 调用链偏长

2. Pinia 更像“多个并列 store”

Pinia 不强调必须塞进一个大仓库,而是:

  • 用户一个 store
  • 权限一个 store
  • 购物车一个 store

例如:

export const useUserStore = defineStore('user', {
state: () => ({ token: '', profile: null }),
})

这种方式更符合组合式思维:谁需要,就引谁。

四、核心差异三:TypeScript 体验

这是 Pinia 很大的优势。

1. Vuex 的 TS 体验为什么一般

不是不能写 TS,而是:

  • 类型推导链条不够顺
  • commit / dispatch 字符串化调用较多
  • 模块组合后类型维护成本偏高

2. Pinia 的 TS 为什么更自然

因为它 API 更贴近普通对象和函数:

  • state 返回什么,类型通常就能推出来
  • gettersactionsthis 类型更顺
  • 在组件中使用 store 时,IDE 提示更完整

所以在中大型 Vue 3 + TS 项目里,Pinia 的开发体验通常更好。

五、核心差异四:和 Vue 3 的契合度

Vuex 当然能在 Vue 3 用,但它整体思维仍更偏 Vue 2 时代。

Pinia 则明显更贴合:

  • Composition API
  • setup() 中按需引入 store
  • 更自然的模块拆分

示例:

import { useUserStore } from '@/stores/user'

const userStore = useUserStore()

这个体验和使用 composable 很接近。

六、什么时候选 Vuex,什么时候选 Pinia

1. 新项目

一般结论很明确:

  • Vue 3 新项目:优先 Pinia

原因:

  • 官方推荐方向
  • 样板代码更少
  • TS 更友好
  • 和现代 Vue 写法更统一

2. 老项目

如果项目已经深度使用 Vuex,不一定要为了“新”而迁移。

要看:

  • 模块数量是否很多
  • 团队是否熟悉 Vuex
  • 迁移收益是否大于成本
  • 是否顺带在做 Vue 3 / TS / 架构升级

也就是说,新项目看推荐,老项目看成本。

七、对比表

维度VuexPinia
官方推荐度历史主流,遗留项目常见Vue 3 新项目主推
状态修改方式强调 mutation可直接在 action/实例上改
组织方式单仓库 + modules多 store 并列
TypeScript 体验一般更好
样板代码较多更少
与 Composition API 契合度一般更高
迁移成本旧项目已存在新项目接入轻量

八、典型题 & 标准答法

Q1:Pinia 为什么要去掉 mutation

:因为在很多业务里,mutationaction 被拆成两层后,收益并不总能覆盖样板代码成本。Pinia 认为状态变更依然应该可追踪,但不必强制每次修改都先走一层 mutation,所以改成更直接的写法。

Q2:Vuex 和 Pinia 最大区别是什么?

:表层看是 API 更简洁,深层看是设计哲学不同。Vuex 更强调中心化和严格约束,Pinia 更强调组合式、轻量和类型友好。一个像“规范化的大仓库”,一个像“按领域拆分的多个 store”。

Q3:老项目要不要从 Vuex 迁到 Pinia?

:不应该一刀切。如果项目已经稳定、团队也熟悉 Vuex,迁移未必立刻有高收益;如果项目本身正好在做 Vue 3、TypeScript、组合式 API 升级,那顺带迁到 Pinia 会更合理。

九、易错点 / 坑

  • 把 Pinia 理解成“只是 Vuex 的精简版”。
  • 以为没有 mutation 就等于状态变更不可控。
  • 只谈语法简洁,不谈组织方式和 TS 体验。
  • 把“官方推荐”误解成“必须无脑迁移”。

速记要点

  • Vuex:中心化、约束强、历史项目常见
  • Pinia:轻量、TS 友好、Vue 3 推荐
  • 最大变化:去掉强制 mutation
  • 组织方式:modules vs 多 store
  • 选择原则:新项目优先 Pinia,老项目按成本决策