主题
概念卡片: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 改 statestore 三件套
| 成员 | 类比 | 说明 |
|---|---|---|
state | data | 共享数据,必须是函数返回对象 |
getters | computed | 派生状态,可传参 |
actions | methods | 同步/异步都支持,直接改 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时按需引入。
关联
- 总览:Vue3技术栈总览
- 路由:概念卡片:VueRouter路由机制
- 对标 Redux:概念卡片:Redux状态管理
- 源:
B40-资源/语雀-Leo的知识库/框架与vue3/05_Vue3/11_状态管理Pinia/02_Pinia轻量级状态管理库