一. 对比
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 }
}
};
可根据项目需要选择对应的状态管理库。