本文作者: LIO
Pinia 就是 Vue3 的官方状态管理库,用来全局共享数据(比如用户信息、token、主题、全局状态)。
一、先安装 Pinia
npm install pinia
# 或
yarn add pinia
# 或
pnpm add pinia
二、在 main.ts/main.js 全局注册
import { createApp } from 'vue'
import { createPinia } from 'pinia' // 引入
import App from './App.vue'
const app = createApp(App)
app.use(createPinia()) // 注册
app.mount('#app')
三、创建一个 Store(核心)
在 src/stores/ 文件夹下创建文件,例如:src/stores/counter.js 或 counter.ts
// 1. 引入 defineStore
import { defineStore } from 'pinia'
// 2. 创建并导出 Store
// 'counter' 是唯一 id,不能重复
export const useCounterStore = defineStore('counter', {
// 状态数据(相当于 data)
state: () => ({
count: 0,
name: 'Pinia测试'
}),
// 计算属性(相当于 computed)
getters: {
doubleCount: (state) => state.count * 2
},
// 修改/操作方法(相当于 methods)
actions: {
increment() {
this.count++
},
updateName(newName) {
this.name = newName
}
}
})
四、在 Vue 组件中使用(组合式 API)
<template>
<div>
<h2>计数:{{ counterStore.count }}</h2>
<p>双倍:{{ counterStore.doubleCount }}</p>
<button @click="counterStore.increment">+1</button>
</div>
</template>
<script setup>
// 引入你定义的 store
import { useCounterStore } from '@/stores/counter'
// 拿到 store 实例
const counterStore = useCounterStore()
</script>
直接用:
- 读数据:
counterStore.count - 调用方法:
counterStore.increment()
五、常用 4 种修改 state 的方式
1. 直接修改(最简单)
counterStore.count = 100
2. 批量修改
counterStore.$patch({
count: 10,
name: '新名称'
})
3. 用 actions 修改(推荐)
counterStore.increment()
4. 重置 state
counterStore.$reset()
六、结构赋值(保持响应式)
Pinia 直接解构会失去响应式,必须用 storeToRefs:
import { storeToRefs } from 'pinia'
const counterStore = useCounterStore()
// ✅ 正确:保持响应式
const { count, doubleCount } = storeToRefs(counterStore)
七、持久化(刷新不丢失数据)
安装插件:
npm i pinia-plugin-persistedstate
在 main.ts 注册:
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
在 store 里开启:
export const useCounterStore = defineStore('counter', {
state: () => ({ ... }),
persist: true // 开启持久化
})
八、最常用的业务场景:用户状态
示例 stores/user.js:
export const useUserStore = defineStore('user', {
state: () => ({
token: '',
userInfo: null
}),
actions: {
login(data) {
this.token = data.token
this.userInfo = data.userInfo
},
logout() {
this.$reset()
}
},
persist: true
})
组件使用:
const userStore = useUserStore()
userStore.login({ token: 'xxx', userInfo: { name: '张三' } })
总结(记住这 4 句就够了)
- Pinia = 全局共享数据
defineStore创建仓库state存数据,getters计算,actions改数据- 组件中直接调用,
storeToRefs解构保持响应式