Vuex和Pinia状态管理

Vuex 和 Pinia 都是 Vue 生态中的状态管理库,但它们的定位和设计理念有本质区别。Pinia 是 Vue 官方目前推荐的状态管理方案,Vuex 已进入维护模式,不再适用于新项目。

📦 Vuex:传统的集中式状态管理

Vuex 是 Vue 2 时代官方推荐的状态管理库,遵循 Flux 架构,采用严格的单向数据流,专为大型复杂应用设计,以确保状态变化的可预测性。

核心概念:

· State:单一状态树,存放所有共享数据。

· Getters:从 State 派生数据,类似计算属性。

· Mutations:唯一可以同步修改 State 的地方。

· Actions:处理异步逻辑,通过 commit 触发 Mutation 间接更新状态。

· Modules:将 Store 分割成模块,通过命名空间管理。

Vuex 的严格规范在大型团队中有利于代码规范,但也带来了大量样板代码和复杂的 TypeScript 类型声明等问题。

🌿 Pinia:Vue 3 的现代化状态管理

Pinia 由 Vue 核心团队成员开发,最初被称为 "Vuex 5",但并非 Vuex 的升级版,而是从设计理念上就不同的替代方案。它深度整合 Vue 3 的 Composition API 和响应式系统,API 极其简洁。

核心概念:

· State:使用函数返回初始状态,更符合 Vue 3 风格。

· Getters:类似 Vue 的计算属性,写法更直观。

· Actions:取消了 Mutations,可以直接修改 State,同时支持同步和异步操作。

📊 核心差异对比

对比维度 Vuex Pinia

API 设计 复杂,需区分 Mutations/Actions 极简,无 Mutations,Actions 直接改 State

TypeScript 支持 需大量手写类型声明,体验较差 开箱即用的完整类型推导,IDE 自动补全精准

模块化 单一 Store 树,嵌套 Modules,访问路径冗长 多 Store 设计,独立定义,可互相 import 引用

体积 稍大 约 1.5kb,极其轻量

代码量 样板代码多 通常减少 30%--50%

Vue 版本 支持 Vue 2 和 Vue 3 专为 Vue 3 设计,也支持 Vue 2

官方定位 维护模式,不推荐用于新代码 官方默认推荐的状态管理方案

🎯 如何选择?

新项目:直接选择 Pinia。它是 Vue 官方推荐,API 简洁、TS 体验优秀、体积小巧,是当前 Vue 3 生态的绝对主流。

存量 Vuex 项目:不必急于全量迁移,可采用渐进式迁移------新功能用 Pinia 开发,旧模块在维护中逐步迁移;也可通过"桥接 Store"让两者共存,优先迁移用户信息、权限等核心状态。

仅需简单状态共享:如果应用只有两三个页面,使用 Vue 3 自身的 ref/reactive 配合 provide/inject 即可,无需引入任何状态管理库。

💎 总结

Pinia 并非 Vuex 的简单升级,而是一次设计理念的革新------用更少的 API、更好的类型支持、更自然的模块化,解决了 Vuex 长期存在的样板代码多、TS 体验差、模块嵌套复杂等痛点。对于 2026 年的 Vue 开发者而言,Pinia 已是默认选择,Vuex 则属于需要维护的历史项目。

下面分别对 Vuex 和 Pinia 做详细拆解,包括设计思想、核心概念、代码示例、优缺点和适用场景。


一、Vuex 详解

  1. 是什么

Vuex 是 Vue 2 时代官方推荐的状态管理库,受 Flux、Redux 启发,采用集中式存储管理组件间共享状态,并通过一套规则保证状态变化可预测、可追踪。

Vuex 4 适配 Vue 3,Vuex 3 适配 Vue 2。目前 Vuex 已进入维护模式,官方不再推荐用于新项目。

  1. 核心思想

· 单一状态树:整个应用只有一个 Store,所有共享状态集中存放。

· 单向数据流:组件不能直接修改 State,必须通过 Mutation。

· 严格同步:Mutation 必须同步,异步逻辑放在 Action 中。

  1. 核心概念

概念 作用 特点

State 存储共享数据 单一状态树,唯一数据源

Getters 从 State 派生数据 类似计算属性,可缓存

Mutations 修改 State 的唯一方式 必须同步,通过 commit 触发

Actions 处理异步逻辑 通过 dispatch 触发,内部 commit Mutation

Modules 拆分 Store 可命名空间隔离,避免冲突

  1. 工作流程

    组件 dispatch Action
    ↓
    Action 执行异步操作
    ↓
    Action commit Mutation
    ↓
    Mutation 同步修改 State
    ↓
    State 更新,组件重新渲染

  2. 代码示例

创建 Store:

js 复制代码
// store/index.js
import { createStore } from 'vuex'

export default createStore({
  state: {
    count: 0
  },
  getters: {
    doubleCount: (state) => state.count * 2
  },
  mutations: {
    INCREMENT(state, payload) {
      state.count += payload
    }
  },
  actions: {
    incrementAsync({ commit }, payload) {
      setTimeout(() => {
        commit('INCREMENT', payload)
      }, 1000)
    }
  },
  modules: {
    // 模块化
  }
})

组件中使用:

vue 复制代码
<script setup>
import { computed } from 'vue'
import { useStore } from 'vuex'

const store = useStore()

const count = computed(() => store.state.count)
const doubleCount = computed(() => store.getters.doubleCount)

const increment = () => store.commit('INCREMENT', 1)
const incrementAsync = () => store.dispatch('incrementAsync', 1)
</script>
  1. TypeScript 支持

Vuex 的 TS 支持较弱,需要手动声明类型:

ts 复制代码
// 需要定义 InjectionKey、State 类型、模块类型等
const store = useStore<State>()

模块嵌套后类型推导复杂,通常需要大量手写类型声明。

  1. 优缺点

优点:

· 规范严格,状态变更可追踪

· DevTools 支持时间旅行

· 生态成熟,适合大型团队协作

· 模块化支持命名空间

缺点:

· 样板代码多,概念多

· 必须区分 Mutation 和 Action

· TypeScript 体验差

· 模块嵌套复杂,访问路径冗长

· 体积较大

  1. 适用场景

· Vue 2 老项目

· 已使用 Vuex 的存量项目维护

· 需要严格状态追踪的大型应用

· 团队已熟悉 Vuex 规范


二、Pinia 详解

  1. 是什么

Pinia 是 Vue 官方目前推荐的状态管理库,由 Vue 核心团队成员开发,最初被称为 "Vuex 5",但设计理念完全不同。它深度整合 Vue 3 的 Composition API,API 极简,TypeScript 支持极佳。

Pinia 支持 Vue 2 和 Vue 3,但主要面向 Vue 3。

  1. 核心特点

· 无 Mutations:只有 State、Getters、Actions

· Actions 可直接修改 State:同步异步都支持

· 多 Store 设计:每个 Store 独立,可互相引用

· 完整 TypeScript 类型推导:开箱即用

· 极轻量:约 1.5kb

· DevTools 支持:时间旅行、热更新

· 插件系统:持久化、日志等

  1. 核心概念

概念 作用 特点

Store 独立的状态容器 通过 defineStore 定义

State 存储数据 可直接修改

Getters 派生数据 类似计算属性

Actions 业务逻辑 同步/异步均可,直接改 State

  1. 两种定义方式

选项式 Store:

js 复制代码
// stores/counter.js
import { defineStore } from 'pinia'

export const useCounterStore = defineStore('counter', {
  state: () => ({
    count: 0
  }),
  getters: {
    doubleCount: (state) => state.count * 2
  },
  actions: {
    increment(payload) {
      this.count += payload
    },
    async incrementAsync(payload) {
      await new Promise((r) => setTimeout(r, 1000))
      this.increment(payload)
    }
  }
})

组合式 Store(推荐):

js 复制代码
// stores/counter.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'

export const useCounterStore = defineStore('counter', () => {
  const count = ref(0)
  const doubleCount = computed(() => count.value * 2)

  function increment(payload) {
    count.value += payload
  }

  async function incrementAsync(payload) {
    await new Promise((r) => setTimeout(r, 1000))
    increment(payload)
  }

  return { count, doubleCount, increment, incrementAsync }
})
  1. 组件中使用
vue 复制代码
<script setup>
import { storeToRefs } from 'pinia'
import { useCounterStore } from '@/stores/counter'

const counter = useCounterStore()

// 解构 state 和 getters 并保持响应性
const { count, doubleCount } = storeToRefs(counter)

// actions 可以直接解构
const { increment, incrementAsync } = counter
</script>

<template>
  <p>count: {{ count }}</p>
  <p>double: {{ doubleCount }}</p>
  <button @click="increment(1)">+1</button>
  <button @click="incrementAsync(1)">异步 +1</button>
</template>
  1. 常用 API

· $patch:批量修改 State

js 复制代码
counter.$patch({ count: 10 })
counter.$patch((state) => { state.count = 10 })

· $reset:重置 State

· 选项式 Store 自带

· 组合式 Store 需手动实现

· $subscribe:监听 State 变化

js 复制代码
counter.$subscribe((mutation, state) => {
  console.log(state.count)
})

· $onAction:监听 Action 调用

js 复制代码
counter.$onAction(({ name, args, after, onError }) => {
  console.log(`Action ${name} 被调用`)
})
  1. 模块化与互相引用

每个 Store 独立文件,直接 import 即可:

js 复制代码
// stores/user.js
import { defineStore } from 'pinia'
import { useCartStore } from './cart'

export const useUserStore = defineStore('user', () => {
  const cart = useCartStore()

  function checkout() {
    cart.clear()
  }

  return { checkout }
})
  1. TypeScript 支持

Pinia 自动推导类型,无需额外声明:

ts 复制代码
const counter = useCounterStore()
counter.count // number
counter.increment(1) // 参数类型自动推导
  1. 优缺点

优点:

· API 极简,学习成本低

· TypeScript 体验极佳

· 模块化自然,多 Store 独立

· 轻量,体积小

· 官方推荐,生态活跃

· DevTools 支持完善

缺点:

· 从 Vuex 迁移需要一定成本

· 部分旧插件只支持 Vuex

· 组合式 Store 的 $reset 需手动实现

  1. 适用场景

· Vue 3 新项目

· TypeScript 项目

· 中小型到大型应用

· 希望代码简洁、类型安全的团队


三、总结对比

维度 Vuex Pinia

官方定位 维护模式 官方推荐

API 风格 复杂,Mutations + Actions 极简,只有 Actions

修改 State 必须通过 Mutation 可直接修改

TypeScript 需手动声明 自动推导

模块化 嵌套 Modules 多 Store 独立

体积 较大 约 1.5kb

学习成本 较高 较低

适用项目 Vue 2 老项目 Vue 3 新项目

选择建议:

· 新项目:直接用 Pinia

· 老项目:渐进式迁移,新功能用 Pinia,旧模块逐步替换

· 简单共享状态:ref/reactive + provide/inject 即可,无需状态管理库

Pinia 已成为 Vue 3 生态的事实标准,Vuex 则属于需要维护的历史方案。

相关推荐
VX_bysjlw9852 小时前
数码设备销售网站设计与实现39138-计算机毕设原创(免费领源码+带部署教程)
java·vue.js·spring boot·mysql·tomcat·mybatis·idea
whi7 小时前
一个小工具,解决了一个困扰 Vue 开发者多年的类型检查难题
vue.js·typescript
xcs1940518 小时前
前端 vue 的前端页面debugger 进不去
前端·javascript·vue.js
雪芽蓝域zzs1 天前
第 5 节:Marker 点击弹出 InfoWindow 信息窗口
vue.js
大包子1 天前
structuredClone vs lodash.cloneDeep:核心差异与选型指南
javascript·vue.js
雪芽蓝域zzs1 天前
第 3 节:地图点击事件,点击获取经纬度
vue.js
WayneX1 天前
开源 Vue 3 组件库 Morya UI:把组件、文档、AI 工具链一起做进一个包
前端·vue.js·前端框架
hai_android1 天前
Chat 聊天模块功能总结
前端·javascript·vue.js
志尊宝1 天前
Vue3 零基础每日笔记(076):防抖节流的正确使用——搜索框、按钮防重复提交、滚动监听
javascript·vue.js·笔记