Pinia 是 Vue 官方推荐的新一代状态管理库 ,专为 Vue3 设计,用来替代 Vuex。它以"轻量、直观、TypeScript 友好"著称,核心只有 state(数据) 、getters(计算值) 和 actions(方法) 三个概念。
一、Pinia 是什么
-
定义:一个"全局数据仓库",跨组件/页面共享状态,与组件树解耦
-
与 Vuex 对比
- 去掉 Mutation,同步异步都写在 actions 里。
- 无需嵌套模块,每个 store 天然独立
- 体积 ≈ 1 kB;支持 Vue2 / 3 和 SSR。
- 配合 TypeScript 类型推导极佳
二、安装与启动
js
# npm
npm i pinia
# main.ts
import { createPinia } from 'pinia'
app.use(createPinia())
三、创建 Store(两种语法)
- Option 风格(类 Vuex)
ts
// src/stores/counter.ts
import { defineStore } from 'pinia'
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
getters: {
double: (state) => state.count * 2
},
actions: {
increment() { this.count++ },
async asyncAdd(n: number) {
await delay(500)
this.count += n
}
}
})
- Setup 风格(Composition API)
ts
export const useCounterStore = defineStore('counter', () => {
const count = ref(0)
const double = computed(() => count.value * 2)
function increment() { count.value++ }
return { count, double, increment }
})
四、在组件里使用
vue
<script setup>
import { useCounterStore } from '@/stores/counter'
import { storeToRefs } from 'pinia'
const store = useCounterStore()
// 保持响应式解构
const { count, double } = storeToRefs(store)
// 方法直接解构即可
const { increment, asyncAdd } = store
</script>
<template>
<p>{{ count }} / {{ double }}</p>
<button @click="increment">+1</button>
<button @click="asyncAdd(5)">async +5</button>
</template>
五、操作 state 的常见姿势
需求 | 写法示例(在组件内) |
---|---|
直接改 | store.count = 10 |
批量改 | store.$patch({ count: 10, msg:'ok' }) 或传入函数 |
整体替换 | store.$state = { count: 0, ... } |
重置为初始值 | store.$reset() |
六、数据持久化(刷新不丢)
css
npm i pinia-plugin-persistedstate
TS
// main.ts
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
pinia.use(piniaPluginPersistedstate)
// store 里打开开关
export const useCounterStore = defineStore('counter', {
state: () => ({ count: 0 }),
persist: true // 默认存在 localStorage
})
七、调试与 DevTools
- 安装 Vue DevTools 6+ 即可看到所有 store 的实时值、调用栈。
- 生产环境默认关闭,可手动开启
pinia.use(devtools)
。
八、小结(记住 3 句话)
- "全局变量"放 state,需要缓存的计算值放 getters,改数据全写 actions。
- 组件里
storeToRefs
保住响应式,方法直接解构。 - 想持久化就装
pinia-plugin-persistedstate
,一行persist: true
搞定。