总结对比表
对比项 | Vuex | Pinia |
---|---|---|
API 设计 | 区分 mutations /actions | 仅 state /actions /getters |
模块化 | 嵌套式配置 | 独立 Store,按需组合 |
TypeScript | 需手动声明类型 | 原生自动推断 |
代码简洁性 | 冗余(需 commit /dispatch ) | 直接调用方法 |
推荐场景 | Vue 2 升级项目/严格规范 | Vue 3 新项目/灵活简洁 |
Vue 3 中 Pinia 和 Vuex 的核心区别及代码对比:
1. 核心 API 对比
Vuex 示例
// store.js
import { createStore } from 'vuex';
export default createStore({
state: {
count: 0
},
mutations: {
increment(state) {
state.count++; // 必须通过 mutations 同步修改
}
},
actions: {
incrementAsync({ commit }) {
setTimeout(() => {
commit('increment'); // 异步操作需调用 commit
}, 1000);
}
},
getters: {
doubleCount: (state) => state.count * 2
}
});
Pinia 示例
// counterStore.js
import { defineStore } from 'pinia';
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
actions: {
increment() {
this.count++; // 直接通过 this 修改状态
},
async incrementAsync() {
setTimeout(() => {
this.increment(); // 支持异步操作
}, 1000);
}
},
getters: {
doubleCount: (state) => state.count * 2
}
});
关键差异:
- Pinia 移除
mutations
,允许在actions
中直接修改状态(同步/异步均可)。 - Vuex 强制区分
mutations
(同步)和actions
(异步)。
2. 模块化对比
Vuex 模块化(嵌套式)
// userModule.js
export default {
state: { name: 'User' },
mutations: { ... }
};
// store.js
import userModule from './userModule';
export default createStore({
modules: {
user: userModule // 嵌套式模块
}
});
Pinia 模块化(扁平化)
// userStore.js
export const useUserStore = defineStore('user', {
state: () => ({ name: 'User' })
});
// productStore.js
export const useProductStore = defineStore('product', { ... });
关键差异:
- Vuex 需在单一 Store 中嵌套模块;Pinia 支持独立定义 Store,按需引入。
3. 组件中使用对比
Vuex 组件调用
<template>
<div>{{ $store.state.count }}</div>
<button @click="$store.commit('increment')">同步 +1</button>
<button @click="$store.dispatch('incrementAsync')">异步 +1</button>
</template>
Pinia 组件调用
<template>
<div>{{ counterStore.count }}</div>
<button @click="counterStore.increment()">同步 +1</button>
<button @click="counterStore.incrementAsync()">异步 +1</button>
</template>
<script setup>
import { useCounterStore } from './counterStore';
const counterStore = useCounterStore();
</script>
关键差异:
- Pinia 通过 Store 实例直接调用方法,代码更简洁;Vuex 需通过
commit
/dispatch
。
4. TypeScript 支持对比
Vuex 类型声明(手动)
// 需手动定义类型
interface State {
count: number;
}
const store = createStore<State>({
state: { count: 0 },
mutations: {
increment(state) {
state.count++; // 需手动确保类型匹配
}
}
});
Pinia 类型推断(自动)
// 自动推断类型
const counterStore = useCounterStore();
counterStore.increment(); // 方法名和参数自动提示
counterStore.count++; // 直接修改状态(需配置允许)
关键差异:
- Pinia 原生支持 TypeScript 类型推断;Vuex 需手动配置类型。
5. 响应式解构对比
Pinia 的响应式解构
import { storeToRefs } from 'pinia';
const counterStore = useCounterStore();
const { count, doubleCount } = storeToRefs(counterStore); // 解构后仍保持响应式
Vuex 的局限性:
- Vuex 解构
$store.state.count
会失去响应性,需通过computed
包装。
总结对比表
对比项 | Vuex | Pinia |
---|---|---|
API 设计 | 区分 mutations /actions | 仅 state /actions /getters |
模块化 | 嵌套式配置 | 独立 Store,按需组合 |
TypeScript | 需手动声明类型 | 原生自动推断 |
代码简洁性 | 冗余(需 commit /dispatch ) | 直接调用方法 |
推荐场景 | Vue 2 升级项目/严格规范 | Vue 3 新项目/灵活简洁 |