Vuex和pinia的区别

0 阅读1分钟

最近改一个vue2+vuex的项目,发现很不方便,学过pinia感觉方便很多

首先,什么是Vuex和pinia,他们是 vue.js生态中的 状态管理 工具

Vuex的四个核心概念 : state (数据)、getters (计算属性)、mutations (修改state数据)、actions(方法)

const store = new Vuex.Store({
    state: {
      count: 0,
      user: null
    },

    getters: {
      doubleCount(state) {
        return state.count * 2
      }
    },

    mutations: {
      increment(state) {
        state.count++  
      }
    },

    actions: {
      async increment({ commit }) {
        await someAsyncTask()  
        commit('increment')    
      }
    }
  })

Vuex挂载到vue示例上

import Vuex from 'vuex'
Vue.use(Vuex)
const store = new Vuex.Store({...})

Vuex设计mutations是为了

  • 确保状态变更的可追踪性(通过devtools)
  • 强制同步操作,使状态变更可预测
  • 实现"单向数据流"的设计模式

人话版: 为了标记是谁改了他 如何使用Vuex

// 在组件中使用 state
this.$store.state.count

// 使用 getters
this.$store.getters.doubleCount

// 使用 mutations(同步修改state)
this.$store.commit('increment')
this.$store.commit('increment', 10) // 传参

// 使用 actions(异步操作)
this.$store.dispatch('increment')

pinia的三个核心概念(舍弃了mutations): state (数据)、getters (计算属性)actions(方法)

import { defineStore } from 'pinia'

  export const useCartStore = defineStore('cart', {
    state: () => ({
      items: [],
      total: 0
    }),

    getters: {
      itemCount(state) {
        return state.items.length
      }
    },

    actions: {
      async addItem(product) {
        const stock = await checkStock(product.id)
        if (stock > 0) {
          this.items.push({
            ...product,
            quantity: 1
          })
        }
      }
    }
  })

pinia安装到vue实例上

 import { createPinia } from 'pinia'
  const pinia = createPinia()
  app.use(pinia)

pinia舍弃掉mutations的原因

  • Pinia简化了API设计
  • actions可以直接修改state
  • 移除mutations减少了代码层级,提高了开发体验
  • 仍然保持状态变更的可追踪性

人话版: 因为vue3的响应式设计,他可以通过调用栈来得知谁修改了 如何去使用 pinia

<script setup>
  import { useCartStore } from '@/stores/cart' 

  const cart = useCartStore()

  console.log(cart.items)        // state
  console.log(cart.totalPrice)   // getter
  cart.addItem(product)          // action
</script>

pinia和vuex的区别

  1. 代码量 - Pinia代码更简洁,去掉了mutations
  2. TypeScript的支持 - Pinia天然支持TypeScript,类型推断更好
  3. 模块化设计
    • Vuex:需要手动配置modules,使用命名空间
    • Pinia:每个store独立,天然模块化
  4. 挂载方式
    • Vuex:必须挂载到Vue实例(Vue.use(Vuex)
    • Pinia:按需导入,不需要挂载到实例
  5. 状态修改
    • Vuex:state → mutation → action(三层)
    • Pinia:state → action(两层,action可直接修改state)
  6. Devtools支持 - 两者都支持,但Pinia的追踪更直观
  7. Vue版本支持
    • Vuex:主要用于Vue 2
    • Pinia:Vue 3官方推荐,也有Vue 2版本
  8. State访问
    • Vuex:this.$store.state.xxx
    • Pinia:直接store.xxx,更符合直觉

TypeScript支持示例

// TypeScript 示例
interface User {
  id: number
  name: string
}

export const useUserStore = defineStore('user', {
  state: () => ({
    user: null as User | null,
    isLoading: false
  }),

  getters: {
    userName(): string {
      return this.user?.name || 'Guest'
    }
  }
})

总结:Pinia作为Vuex的继任者,在API设计、开发体验和TypeScript支持上都有显著提升。新项目建议优先选择Pinia。