Pinia 与 Vuex 在 Vue 3 中的使用区别
本篇文章面向各位前端Vuer初学者,重点介绍在 Vue 3 中使用 Pinia 与 Vuex 的差异,主要在日常使用上区分一下
一、状态定义方式对比
1. Vuex 定义方式
Vuex 的状态管理采用集中式设计,核心包括 state、getters、mutations 和 actions:
// store/index.js
import { createStore } from 'vuex'
export const store = createStore({
state: () => ({
count: 0
}),
getters: {
doubleCount (state) {
return state.count * 2
}
},
mutations: {
increment (state) {
state.count++
}
},
actions: {
asyncIncrement ({ commit }) {
setTimeout(() => {
commit('increment')
}, 1000)
}
}
})
- 所有状态变更必须通过
mutations完成。 actions用于异步操作,需通过commit调用 mutation。
2. Pinia中option 定义方式
Pinia option store 写法,使用 defineStore 定义每个 store,省略 mutation,直接在 action 中修改状态:
// stores/counter.js
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({
count: 0
}),
getters: {
doubleCount: (state) => state.count * 2
},
actions: {
increment() {
this.count++
},
asyncIncrement() {
setTimeout(() => {
this.increment()
}, 1000)
}
}
})
- 状态可直接通过
this修改,无需 mutation。 actions支持同步与异步处理,调用简单:counterStore.increment()。
3. Pinia 中的组合式写法
Pinia 也支持更加灵活的组合式写法(setup store模式),更贴近 Vue 3 的风格:
// stores/counterSetup.js
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
export const useCounterSetupStore = defineStore('counterSetup', () => {
const count = ref(0)
const doubleCount = computed(() => count.value * 2)
function increment() {
count.value++
}
return {
count,
doubleCount,
increment
}
})
使用组合式写法后,Pinia store 更像普通的 Vue 3 组合式逻辑,可与其他 Composition API 模块轻松组合。
二、模块化处理方式对比
1. Vuex 模块化
Vuex 通过 modules 属性集中注册子模块,结构树状、层级明确:
// store/modules/user.js
export const user = {
namespaced: true,
state: () => ({
name: 'Alice'
}),
mutations: {
setName (state, name) {
state.name = name
}
},
actions: {
updateName({ commit }, name) {
commit('setName', name)
}
}
}
// store/index.js
import { createStore } from 'vuex'
import { user } from './modules/user'
export const store = createStore({
modules: {
user
}
})
- 模块需统一集中注册。
- 使用时需携带模块名访问:
store.commit('user/setName', 'Bob')。
2. Pinia 模块化
Pinia 中,每个 store 都是独立模块,不需集中注册,按需引入即可:
// stores/userStore.js
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', {
state: () => ({
name: 'Alice'
}),
actions: {
setName(name) {
this.name = name
}
}
})
使用方式:
// 在组件中使用
const userStore = useUserStore()
userStore.setName('Bob')
- 无需模块嵌套与命名空间问题。
- 各模块按需导入,结构清晰、松耦合。
三、小结
| 对比点 | Vuex | Pinia |
|---|---|---|
| 状态定义方式 | 需要配置 state / getters / mutations / actions | 可省略 mutation,支持 setup 风格 |
| 状态修改方式 | 必须通过 commit | 可在 action 中直接修改 state |
| 模块组织 | modules 统一注册 | 独立模块,按需引入 |
总体来说,Pinia 在 Vue 3 项目中更符合组合式开发理念,API 简洁、类型友好,是目前 Vue 官方推荐的状态管理方案。