一、核心思想没变,但更简单了
全局状态的定义没变,依然是"整个项目共享的数据仓库"。
Pinia 的核心理念就是你总结的那张流程图,但它把流程极度简化了:
text
组件页面
↓(直接调用)
Actions(包含异步请求 + 修改数据)
↓ 直接修改
State(全局数据)
↓ 数据更新
所有页面自动更新
最大的变化:砍掉了 Mutations,Actions 可以直接改 State。
二、5 个核心概念对照表
| 你的总结 (Vuex) | Pinia 对应 | 变化说明 |
|---|---|---|
| State (存数据) | State (存数据) | 完全一样 ,用 ref() 或 state: () => ({}) |
| Getters (计算数据) | Getters (计算数据) | 完全一样 ,用 computed() 或 getters: {} |
| Mutations (唯一改数据) | 🪓 被砍掉了 | 最大区别:不再需要,Actions 直接改 |
| Actions (异步逻辑) | Actions (异步 + 修改一把梭) | 函数里既能发请求,又能直接改 State |
| Modules (代码分割) | 多个独立 Store | 自动实现,创建多个 Store 文件即可 |
三、用你的示例直接对比
Vuex 写法(你的代码)
javascript
// Vuex 需要绕一圈
export default new Vuex.Store({
state: { token: '', userInfo: null }, // 1. 存数据
getters: {
getToken: state => state.token // 2. 拿数据
},
mutations: {
SET_TOKEN(state, val) { state.token = val } // 3. 改数据(同步)
},
actions: {
async userLogin({ commit }, formData) { // 4. 业务逻辑(异步)
let res = { token: '123456' }
commit('SET_TOKEN', res.token) // 必须绕道 commit
}
}
})
Pinia 写法(一步到位)
javascript
// stores/user.js
import { defineStore } from 'pinia'
export const useUserStore = defineStore('user', () => {
// --- 1. State:存数据(相当于 Vuex 的 State)---
const token = ref('')
const userInfo = ref(null)
// --- 2. Getters:计算数据(相当于 Vuex 的 Getters)---
const getToken = computed(() => token.value)
// --- 3. Actions:业务逻辑 + 修改数据(一把梭)---
async function userLogin(formData) {
// 直接发请求
const res = { token: '123456', user: { name: '张三' } }
// 💡 直接改!不需要 commit!
token.value = res.token
userInfo.value = res.user
}
return { token, userInfo, getToken, userLogin }
})
四、页面组件使用对比(Vue 3)
Vuex 使用方式
javascript
// Vuex 需要用 mapState, mapActions 辅助函数
import { mapState, mapActions } from 'vuex'
export default {
computed: {
...mapState(['token', 'userInfo'])
},
methods: {
...mapActions(['userLogin']),
handleLogin() {
this.userLogin({ account: 'test' })
}
}
}
Pinia 使用方式
vue
<template>
<div>{{ userInfo }}</div>
</template>
<script setup>
import { useUserStore } from '@/stores/user'
import { storeToRefs } from 'pinia'
const userStore = useUserStore()
// 直接解构,但要用 storeToRefs 保持响应式
const { token, userInfo } = storeToRefs(userStore)
function handleLogin() {
// 直接调用 action,不需要 mapActions
userStore.userLogin({ account: 'test' })
}
</script>
五、你整理的口诀升级版
老口诀(Vuex):
组件调用 dispatch → 走 actions → 提交 commit → 走 mutations → 改 state → 页面自动刷新
新口诀(Pinia,更短更直接):
组件直接调 actions → 改 state → 页面自动刷新
六、必须记住的 3 条新规则
-
改了直接赋值,没有
commit了javascript// ✅ Pinia 正确写法 store.token = 'xxx' // ❌ 以前 Vuex 的老习惯 store.commit('SET_TOKEN', 'xxx') -
异步、同步操作全放在
actions里 不存在 "异步必须放 Actions,同步必须放 Mutations" 的限制了。 -
不再有 Module 嵌套,只有 Flat Store 建一个新文件就是创建了一个新模块,它们是扁平的,可以互相直接引用。
一句话终极总结:
Pinia 就是去掉了 Mutations、砍掉了繁琐语法的 Vuex,让你能更爽地管理全局数据。