你想系统学习 Vue3 官方推荐的状态管理库 Pinia,我会从核心概念、基础使用、模块化、异步操作到实战技巧,用最简单易懂的方式教你完全掌握。
一、核心概念
Pinia 是 Vue 官方新一代状态管理库,替代 Vuex,专为 Vue3 设计,同时兼容 Vue2,核心优势:
- 语法简洁,无需
mutation(只有 state、getters、actions) - 天然支持 TypeScript
- 模块化设计,无需嵌套模块
- 体积更小,性能更高
- 支持热更新、插件扩展
二、快速上手(步骤)
1. 安装 Pinia
# npm
npm install pinia
# yarn
yarn add pinia
# pnpm
pnpm add pinia
2. 在 main.js 全局注册
import { createApp } from 'vue'
import App from './App.vue'
// 引入 Pinia
import { createPinia } from 'pinia'
const app = createApp(App)
// 挂载 Pinia
app.use(createPinia())
app.mount('#app')
三、定义 Store(核心)
Store 是存储状态和业务逻辑的容器,推荐按功能模块化拆分(如 user、cart、setting)。
1. 创建 Store 示例
在 src/stores/ 目录下新建文件(如 user.js):
// src/stores/user.js
import { defineStore } from 'pinia'
// 第一个参数:store 唯一 ID(必须唯一)
// 第二个参数:配置对象
export const useUserStore = defineStore('user', {
// 1. 状态:存储数据(类似 data)
state: () => ({
name: '张三',
age: 20,
token: ''
}),
// 2. 计算属性:派生状态(类似 computed,有缓存)
getters: {
// 自动接收 state 作为参数
doubleAge: (state) => state.age * 2,
// 也可以使用 this 访问整个 store
getName: function() {
return `我的名字:${this.name}`
}
},
// 3. 方法:修改状态、异步请求(类似 methods)
actions: {
// 同步修改
updateName(newName) {
this.name = newName
},
// 异步修改(支持 async/await)
async login(account, pwd) {
// 模拟接口请求
const res = await new Promise(resolve => {
setTimeout(() => resolve({ token: 'abcd-1234' }), 1000)
})
this.token = res.token
this.name = account
}
}
})
四、组件中使用 Store
1. 基础使用(读取/修改状态)
<template>
<div>
<p>姓名:{{ userStore.name }}</p>
<p>年龄:{{ userStore.age }}</p>
<p>双倍年龄:{{ userStore.doubleAge }}</p>
<button @click="userStore.updateName('李四')">改名</button>
<button @click="userStore.login('admin', '123456')">登录</button>
</div>
</template>
<script setup>
// 导入定义好的 store
import { useUserStore } from './stores/user'
// 实例化 store
const userStore = useUserStore()
</script>
2. 解构 state(保持响应式)
直接解构会丢失响应式,必须用 storeToRefs:
import { storeToRefs } from 'pinia'
// 正确写法:响应式解构
const { name, age, doubleAge } = storeToRefs(userStore)
// 注意:actions 不需要解构,直接用
const { updateName, login } = userStore
3. 批量修改 state
// 方式1:单个修改
userStore.name = '王五'
// 方式2:批量修改(推荐)
userStore.$patch({
name: '赵六',
age: 25
})
// 方式3:函数式批量修改(适合复杂逻辑)
userStore.$patch(state => {
state.name = '孙七'
state.age += 1
})
4. 重置 state 到初始值
userStore.$reset()
五、模块化与 Store 相互调用
Pinia 无需配置模块,直接导入其他 Store 即可使用。
示例:cart 购物车 store 调用 user store
// src/stores/cart.js
import { defineStore } from 'pinia'
import { useUserStore } from './user'
export const useCartStore = defineStore('cart', {
state: () => ({
list: []
}),
actions: {
addCart(goods) {
const userStore = useUserStore()
// 判断用户是否登录
if (!userStore.token) {
alert('请先登录')
return
}
this.list.push(goods)
}
}
})
六、数据持久化(常用插件)
页面刷新后 Pinia 数据会丢失,使用 pinia-plugin-persistedstate 插件实现本地持久化。
1. 安装
pnpm add pinia-plugin-persistedstate
2. 全局注册
// main.js
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'
const pinia = createPinia()
pinia.use(piniaPluginPersistedstate)
3. 开启持久化
// 在 store 中添加 persist: true
export const useUserStore = defineStore('user', {
state: () => ({ ... }),
persist: true // 开启持久化(默认 localStorage)
})
七、完整实战总结
- 安装 + 全局注册 Pinia
- 按功能拆分 Store(user/cart 等)
- 用
state存数据、getters做计算、actions做修改/异步 - 组件中导入使用,
storeToRefs解构保持响应式 - 跨模块调用直接导入其他 Store
- 用持久化插件保存数据不丢失
总结
- Pinia 是 Vue3 首选状态库,无 mutation、语法极简
- 核心三部分:
state(数据)、getters(计算)、actions(方法) - 响应式解构必须用
storeToRefs - 模块化天然支持,持久化插件一键配置