当前位置: 首页 > news >正文

Vue3 状态管理 Pinia 入门指南

很多刚接触 Vue3 状态管理的同学都会问:“Vuex 还没学明白,怎么又出了个 Pinia?”这篇就来聊聊 Pinia,看看它到底是什么、为什么要用它、以及怎么用好它。

  1. Pinia 是什么:Pinia 是 Vue 的全新状态管理库,它和 Vuex 有哪些核心区别?
  2. 如何定义 Store:掌握选项式和组合式两种创建 Store 的风格。
  3. 在组件中如何使用:学会在 setup 中正确地使用 Store 并保持响应性。

一、使用场景

Pinia 适用于需要对 Vue 应用进行全局状态管理的场景:

  • 跨组件共享状态:例如用户登录信息、购物车数据、主题配置等
  • 与后端 API 交互:集中管理 API 调用和数据缓存逻辑
  • 调试与开发体验:配合 Vue DevTools 进行状态追踪和时间旅行
  • 类型安全:为 TypeScript 项目提供完整的类型推导支持
  • 模块化管理:将不同领域的全局状态拆分为独立的 Store,易于维护和扩展

二、注意事项

划重点: Pinia 在 Vue 2 和 Vue 3 中均可使用,但本文所有示例均基于 Vue 3 + Script Setup 语法。

  • defineStore的 ID 必须唯一:每个 Store 都需要一个唯一的 ID,用于 DevTools 的连接
  • 没有 mutations​:与 Vuex 不同,Pinia 将状态(state​)与变更逻辑(actions)直接统一,摒弃了繁琐的 mutations
  • 避免过度使用全局状态:组件内部能处理的数据,不要提升到 Store 中

三、基本用法

3.1 安装与配置

yarn add pinia
# 或
npm install pinia

main.ts 中创建 Pinia 实例并注册到 Vue 应用:

// main.ts
import { createApp } from 'vue'
import { createPinia } from 'pinia'
import App from './App.vue'const pinia = createPinia()
const app = createApp(App)app.use(pinia)
app.mount('#app')

3.2 定义 Store

Pinia 提供两种风格来定义 Store:选项式(Options API)组合式(Composition API) 。选择哪个全凭个人喜好,但组合式风格更适合复杂逻辑的复用。

选项式风格:

// stores/counter.ts
import { defineStore } from 'pinia'export const useCounterStore = defineStore('counter', {// 状态(数据)state: () => ({count: 0,name: '我的计数器',}),// 计算属性(派生数据)getters: {// 使用箭头函数时,state 为第一个参数doubleCount: (state) => state.count * 2,// 需要访问其他 getter 时,使用普通函数doubleCountPlusOne(): number {return this.doubleCount + 1},},// 操作方法(业务逻辑)actions: {increment() {this.count++},decrement() {this.count--},// 支持异步操作async incrementAsync() {await new Promise((resolve) => setTimeout(resolve, 1000))this.increment()},incrementBy(amount: number) {this.count += amount},},
})

组合式风格(推荐):

// stores/user.ts
import { defineStore } from 'pinia'
import { ref, computed } from 'vue'
import { api } from '@/services/api' // 假设的 API 服务// 类型定义
interface User {id: numbername: stringemail: string
}
interface LoginCredentials {username: stringpassword: string
}export const useUserStore = defineStore('user', () => {// 状态(类似 options 的 data)const user = ref<User | null>(null)const isLoggedIn = ref(false)// 计算属性(类似 options 的 getters)const userName = computed(() => user.value?.name || '游客')const userId = computed(() => user.value?.id || 0)// 操作方法(类似 options 的 actions)function login(credentials: LoginCredentials) {return api.login(credentials).then((response) => {user.value = response.userisLoggedIn.value = truereturn response})}function logout() {user.value = nullisLoggedIn.value = false}async function fetchUserProfile() {if (!userId.value) returntry {const profile = await api.getUserProfile(userId.value)user.value = { ...user.value, ...profile }} catch (error) {console.error('获取用户资料失败:', error)}}// 返回需要暴露给外部的所有内容return { user, isLoggedIn, userName, userId, login, logout, fetchUserProfile }
})

代码解析:

  1. defineStore:这是定义 Store 的核心函数,第一个参数是 Store 的唯一 ID,第二个参数是 Store 的定义(可以是对象或函数)。
  2. ref​ 和 computed​:在组合式风格中,我们使用 Vue 的响应式 API 来定义状态和计算属性,和写组件 script setup 一模一样。
  3. return语句:组合式 Store 必须 return 一个对象,对象中的属性和方法才能被外部访问。

3.3 在组件中使用 Store

<template><div><h1>{{ counterStore.name }}</h1><p>计数: {{ counterStore.count }}</p><p>双倍计数: {{ counterStore.doubleCount }}</p><p>用户名: {{ userStore.userName }}</p><button @click="counterStore.increment()">增加</button><button @click="counterStore.decrement()">减少</button><button @click="counterStore.incrementBy(5)">增加5</button><button @click="counterStore.incrementAsync()">异步增加</button><button @click="login" v-if="!userStore.isLoggedIn">登录</button><button @click="userStore.logout()" v-else>退出</button></div>
</template><script lang="ts" setup>
import { watch } from 'vue'
import { useCounterStore } from '@/stores/counter'
import { useUserStore } from '@/stores/user'
import { storeToRefs } from 'pinia'const counterStore = useCounterStore()
const userStore = useUserStore()// 关键:使用 storeToRefs 保持解构后的响应性
const { count, doubleCount } = storeToRefs(counterStore)
const { userName, isLoggedIn } = storeToRefs(userStore)// 直接调用 action(action 本身就是方法,无需解构)
const login = () => {userStore.login({ username: 'admin', password: 'password' }).then(() => {console.log('登录成功')}).catch((error) => {console.error('登录失败:', error)})
}// 监听 Store 状态变化
watch(() => counterStore.count,(newCount, oldCount) => {console.log(`计数从 ${oldCount} 变为 ${newCount}`)}
)
</script>

代码解析:

  1. storeToRefs​:这是 Pinia 提供的一个工具函数,用于“解包” Store 的 state 和 getters。直接从 Store 解构 const { count } = counterStore​ 会失去响应性,而 storeToRefs​ 保证了解构后的每个 ref 依然是响应式的。
  2. 直接调用 actions​:actions​ 是普通函数,可以直接从 Store 对象上调用,不需要解构。counterStore.increment()​ 和 userStore.login() 都是正确的用法。
  3. watch监听:你可以像监听普通 ref​ 一样监听 Store 中的状态,使用 watch(() => counterStore.count, handler)

最后

刚接触 Pinia,建议先从最典型的状态(比如用户登录信息、全局配置)开始使用,不要一开始就把所有组件数据都放进 Store。写得顺手了,再逐步将那些频繁跨组件传递的 props 和 emit 改为 Store 管理,你会发现代码瞬间清爽许多。

http://www.jsqmd.com/news/834733/

相关文章:

  • 大一下前三次PTA题目集阶段性总结
  • 2026年5月腐蚀废水电磁流量计国产厂家排名 - 水质仪表品牌排行榜
  • 2026年5月水利外夹式超声波流量计口碑品牌实测 - 水质仪表品牌排行榜
  • 如何使用 fail2ban 配置 SSH 暴力破解自动封禁 IP 策略?
  • 2026 合肥生成式引擎优化(GEO)服务商权威排行榜(满分 100 分) - 安徽工业
  • 2026年|亲测12款论文降AI率工具,效果最稳的竟是它! - 降AI实验室
  • 2026年5月废水处理悬浮物浓度计怎么选?实测推荐 - 液体流量液位品牌推荐
  • 2026年5月专业的张家口成套薯类加工设备厂家怎么选择厂家推荐榜,薯条生产线、马铃薯深加工设备、成套薯类加工设备厂家选择指南 - 海棠依旧大
  • Note - Hall 定理
  • div2 1098
  • 2026年5月口碑好的断桥铝系统窗源头工厂如何选厂家推荐榜:断桥铝系统窗、内开内倒窗、平开窗、推拉窗厂家选择指南 - 海棠依旧大
  • LeetCode 1079. 活字印刷
  • 2026年编辑文章遇AI痕迹困扰?言笔AI助你高效去AI痕迹 - 降AI实验室
  • 深圳外贸圈公认的5家外贸建站服务商,WaiMaoYa(外贸鸭)成工贸一体首选 - 外贸营销工具
  • 2026年5月液体外贴式超声波流量计品牌精选推荐 - 水质仪表品牌排行榜
  • 2026年5月正规的北京外包短视频拍摄公司如何选厂家推荐榜,企业宣传片与信息流广告拍摄团队选择指南 - 海棠依旧大
  • 2026盐城黄金回收哪家靠谱避坑指南与五店实测 - 天天生活分享日志
  • NCHU航空器配载与货运管理系统作业总结
  • 2026年家装益胶泥经销商选型指南:实力合规厂商推荐解析 - 产业观察网
  • 2026年5月镇江黄金回收正规靠谱指南:五家机构多维度测评 - 天天生活分享日志
  • 南昌航空大学软院前三次PTA作业集总结blog
  • 2026年5月行业内郑州腻子粉机器设备全自动公司哪家强厂家推荐榜,全自动腻子粉生产线、干粉砂浆搅拌机、真石漆设备厂家选择指南 - 海棠依旧大
  • 2026年5月正规的烟台发电机出租公司口碑推荐厂家推荐榜:静音发电机、移动发电车、高压发电机厂家选择指南 - 海棠依旧大
  • 深耕本地学情|萧山优质学科辅导机构实力全面解析 - 浙江行业评测
  • 2026年家装益胶泥代理商哪家好:行业选型指南与主流品牌实力解析 - 产业观察网
  • 2026年5月:超声波泥位计十大厂家实测盘点 - 水质仪表品牌排行榜
  • 2026年济南市历城区45天拿证的驾照直营驾校/比较好的驾照金牌驾校 /新规学车的驾照标杆驾校 - 品牌推广大师
  • 2026年5月口碑好的抚顺搬家公司如何选厂家推荐榜:居民搬家、公司搬迁、长途搬家、专项搬运、小型搬家厂家选择指南 - 海棠依旧大
  • 2026年5月热门的羊山新区轻法式装修公司如何选厂家推荐榜,一站式整装与全屋定制厂家选择指南 - 海棠依旧大
  • 2026年家装益胶泥代理商选择深度指南:核心评估维度与靠谱品牌推荐 - 产业观察网