Skip to content

概念卡片:Pinia 状态管理

一句话机制:Pinia 是 Vue3 官方的轻量级状态管理库,用 defineStore 定义一个 store(含 state / getters / actions),让多个组件共享同一份状态;它取代 Vuex,去掉了 mutations,且天然支持模块化(一个文件一个 store,无需 modules 嵌套)。

关键代码示例

定义 store(src/store/index.js):

js
import { defineStore } from 'pinia'
export const useStore = defineStore('storeId', {
  state: () => ({ add: 0, reduce: 100 }),
  getters: { doubleAdd: (state) => state.add * 2 },
  actions: { increase() { this.add++ }, decrease() { this.reduce-- } }
})

挂载 + 组件使用:

js
// main.js
import { createPinia } from 'pinia'
app.use(createPinia())

// 组件里
import { useStore } from './store'
import { storeToRefs } from 'pinia'
const store = useStore()
const { add, reduce } = storeToRefs(store)   // 解构不丢响应式
store.increase()                              // 调 action 改 state

store 三件套

成员类比说明
statedata共享数据,必须是函数返回对象
getterscomputed派生状态,可传参
actionsmethods同步/异步都支持,直接改 state

模块化(对比 Vuex)

复杂项目一个 store 会过大,Pinia 直接按文件分模块:src/store/user.js 放用户、src/store/shop.js 放商品,各 defineStore 后用 useUserStore() / useShopStore() 按需引入——不需要 Vuex 的 modules 嵌套

不变量(必须成立的约束)

  • defineStore('id', {...}) 返回的是 useXxxStore 函数,调用它才拿到 store 实例。
  • 解构 store 会丢失响应式——必须用 storeToRefs(store) 解构,否则拿到普通值快照。
  • Pinia 无需 mutations,可在组件/action 里直接改 state(与 Vuex 最大区别)。
  • store 实例要先 app.use(createPinia()) 挂载,之后才能 useXxxStore()

踩坑案例

  • 现象const { add } = useStore() 解构后,模板里 add 不随 store 更新。 原因:解构切断响应式。解决const { add } = storeToRefs(store)

常见误解

  • 沿用 Vuex 习惯去找 mutations → Pinia 已移除,直接改 state 即可。
  • 以为 store 要像 Vuex 一样集中注册到 modules → Pinia 按文件分模块,use 时按需引入。

关联

最近更新