Vuex 与 pinia

一. 对比

vuex && pinia 都用于

|----------|-----------------------------------------|--------------------------------------------------------|
| 特性 | Vuex | Pinia |
| 核心概念 | state/mutations/actions/getters/modules | state/actions/getters(无 mutations,modules 简化为独立 store) |
| 语法风格 | 选项式 API 为主,适配组合式 API | 完全适配组合式 API,更简洁 |
| 类型支持(TS) | 需手动类型声明,较繁琐 | 天生支持 TS,类型推断更完善 |
| 代码量 | 冗余(如 mutation 的 commit) | 轻量化,代码量少 30%+ |
| 模块嵌套 | 支持 modules 嵌套,需命名空间 | 无嵌套,多个 store 独立,天然隔离 |
| 热更新 / 调试 | 支持,但配置复杂 | 开箱即用,调试体验更好 |
| Vue 版本支持 | Vue 2/Vue 3 | Vue 2/Vue 3(推荐 Vue 3) |
| 官方地位 | 维护中(不再新增功能) | 官方推荐(Vuex 的替代者) |

二. 具体使用

vuex

Vuex 有 5 个核心概念:state(状态)、mutations(同步修改)、actions(异步修改)、getters(计算属性)、modules(模块)。

javascript 复制代码
import { createStore } from 'vuex'

export default createStore({
  // 全局状态
  state: {
    count: 0,
    user: {
        name: '张三',
        age: 20
     }
  },
  // 唯一能同步修改state的地方
  mutations: {
    increment(state) {
      state.count++
    },
    updateUser(state, payload) {
      state.user = payload
    }
  },
  // 处理异步逻辑,最终通过mutations修改state
  actions: {
    async fetchUser({ commit }) {
      const res = await fetch('/api/user')
      const data = await res.json()
      commit('updateUser', data)
    }
  },
  // 基于state的计算属性
  getters: {
    doubleCount: (state) => state.count * 2
  },
  // 模块拆分(解决状态过多的问题)
  modules: {
    cart: {
      namespaced: true, // 命名空间(避免命名冲突)
      state: { goods: [] },
      mutations: { addGoods(state, goods) { state.goods.push(goods) } }
    }
  }
});

组件中使用

javascript 复制代码
// 组件中使用
import { useStore } from 'vuex';

export default {
  setup() {
    const store = useStore()
    // 获取状态
    const count = store.state.count
    const doubleCount = store.getters.doubleCount
    
    // 触发mutation(同步)
    const add = () => store.commit('increment')
    // 触发action(异步)
    const fetchUser = () => store.dispatch('fetchUser')
    
    // 模块内的状态/方法
    const cartGoods = store.state.cart.goods
    const addCartGoods = () => store.commit('cart/addGoods', { name: '商品1' })
    
    return { count, doubleCount, add, fetchUser, cartGoods, addCartGoods }
  }
};

pinia

Pinia 去掉了 mutations,直接通过 actions 处理同步 / 异步,模块(modules)也简化为独立的 store,无需嵌套。

javascript 复制代码
import { defineStore } from 'pinia'

// 定义并导出store(第一个参数是唯一id,必须)
export const useCounterStore = defineStore('counter', {
  // 状态(类似Vuex的state)
  state: () => ({
    count: 0,
    user: { name: '张三', age: 20 }
  }),
  // 计算属性(类似Vuex的getters)
  getters: {
    doubleCount: (state) => state.count * 2,
    // 可以直接调用自身的getters
    tripleCount() {
      return this.doubleCount + this.count
    }
  },
  // 方法(同步/异步都可以,替代Vuex的mutations+actions)
  actions: {
    increment() {
      this.count++ // 直接修改state
    },
    async fetchUser() {
      const res = await fetch('/api/user')
      const data = await res.json()
      this.user = data // 异步修改state,无需commit
    },
    incrementBy(num) {
      this.count += num
    }
  }
});

组件内引入store,按需取值

javascript 复制代码
import { useCounterStore } from '@/store/counter'
import { storeToRefs } from 'pinia' // 辅助函数,保持响应式

export default {
  setup() {
    const counterStore = useCounterStore()
    
    // 方式1:直接获取状态(响应式)
    // 注意:解构会丢失响应式,需用storeToRefs
    const { count, doubleCount } = storeToRefs(counterStore)
    
    // 方式2:直接调用actions
    const add = () => counterStore.increment()
    const fetchUser = () => counterStore.fetchUser()
    const addBy5 = () => counterStore.incrementBy(5)
    
    // 重置state(Pinia内置方法)
    const reset = () => counterStore.$reset()
    
    // 批量修改state
    const updateState = () => {
      counterStore.$patch({
        count: 10,
        user: {
            name: '李四',
            age: 25
         }
      })
    }
    
    return { count, doubleCount, add, fetchUser, addBy5, reset, updateState }
  }
};

可根据项目需要选择对应的状态管理库。

相关推荐
发现一只大呆瓜8 小时前
前端性能优化:图片懒加载的三种手写方案
前端·javascript·面试
不爱吃糖的程序媛9 小时前
Flutter 与 OpenHarmony 通信:Flutter Channel 使用指南
前端·javascript·flutter
利刃大大9 小时前
【Vue】Element-Plus快速入门 && Form && Card && Table && Tree && Dialog && Menu
前端·javascript·vue.js·element-plus
NEXT069 小时前
AI 应用工程化实战:使用 LangChain.js 编排 DeepSeek 复杂工作流
前端·javascript·langchain
念风零壹9 小时前
AI 时代的前端技术:从系统编程到 JavaScript/TypeScript
前端·ai
光影少年10 小时前
react的hooks防抖和节流是怎样做的
前端·javascript·react.js
小毛驴85010 小时前
Vue 路由示例
前端·javascript·vue.js
发现一只大呆瓜10 小时前
AI流式交互:SSE与WebSocket技术选型
前端·javascript·面试
m0_7190841111 小时前
React笔记张天禹
前端·笔记·react.js