Vue3(篇五)pinia状态管理——跨组件数据共享
目录前言一、为什么需要状态管理1.1 组件通信的困境1.2 状态管理的本质二、Pinia 是什么2.1 Pinia vs Vuex2.2 Pinia 的核心概念三、安装与配置3.1 安装3.2 挂载到应用四、定义 Store4.1 基本结构4.2 组合式 API 风格推荐五、使用 Store5.1 在组件中使用5.2 解构 Store5.3 直接修改 State5.4 订阅 State 变化六、实战案例用户认证6.1 用户 Store6.2 登录页面6.3 布局组件显示用户信息6.4 路由守卫使用 Store七、多个 Store7.1 学生 Store7.2 在组件中使用多个 Store八、Pinia 持久化8.1 安装插件8.2 配置插件8.3 在 Store 中启用持久化九、Pinia vs 直接使用 localStorage十、总结Vue3 学习路径总结前言在vue-router单页面应用路由管理中我们掌握了如何管理多个页面。但还有一个问题不同组件之间如何共享数据比如用户信息登录后获取用户信息侧边栏显示用户名右上角显示头像个人中心页展示详细信息。这些组件都需要访问同一份数据。传统做法是用 props 一层层传递或者用 provide/inject但这些方式都不够优雅。Pinia是 Vue3 官方推荐的状态管理库专门解决跨组件数据共享问题。本文将讲解 Pinia 的核心概念Store 的定义与使用、数据的响应式更新、以及与组件的结合。一、为什么需要状态管理1.1 组件通信的困境假设有三个组件需要共享用户信息App.vue ├── Header.vue 需要用户名 ├── Sidebar.vue 需要用户权限 └── Profile.vue 需要完整用户信息方式问题props 传递需要层层传递繁琐provide/inject祖先向后代传递但数据来源不清晰localStorage需要手动同步不是响应式的1.2 状态管理的本质状态管理就是把多个组件共享的数据抽取到一个独立的地方管理┌─────────────────────────────────────┐ │ Store仓库 │ │ ┌─────────────────────────────┐ │ │ │ state: 用户信息、权限等 │ │ │ │ actions: 获取、修改数据的方法 │ │ │ └─────────────────────────────┘ │ └─────────────────────────────────────┘ ↑ ↑ ↑ │ │ │ Header.vue Sidebar.vue Profile.vue类比 Java类似于 Spring 的单例 Bean全局共享所有组件都可以访问。二、Pinia 是什么2.1 Pinia vs VuexPinia 是 Vue3 官方推荐的状态管理库相比 VuexVue2 时代的方案特性VuexPinia代码量多mutations、actions少只有 state、actionsTypeScript支持较弱完美支持Composition API不友好完美支持模块化需要手动分模块每个 Store 独立文件调试工具Vue DevTools 支持Vue DevTools 支持结论Vue3 项目推荐使用 Pinia。2.2 Pinia 的核心概念概念说明类比Store存储共享数据的仓库Java 的 Service 类state数据本身类的成员变量actions操作数据的方法类的方法getters计算属性类的 getter 方法注意Pinia 没有 Vuex 的 mutations直接在 actions 中修改 state 即可。三、安装与配置3.1 安装npminstallpinia3.2 挂载到应用在main.ts中import{createApp}fromvueimport{createPinia}frompiniaimportAppfrom./App.vueimportrouterfrom./routerconstappcreateApp(App)app.use(createPinia())app.use(router)app.mount(#app)四、定义 Store4.1 基本结构新建src/stores/user.tsimport{defineStore}frompinia// 第一个参数是 store 的唯一标识exportconstuseUserStoredefineStore(user,{// state: 数据state:()({name:,age:0,sex:,token:}),// getters: 计算属性getters:{isLogin:(state)!!state.token,userInfo:(state)${state.name}(${state.sex},${state.age}岁)},// actions: 方法actions:{setToken(token:string){this.tokentoken},clearToken(){this.token},asyncfetchUserInfo(){// 调用 API 获取用户信息constdataawaitrequest.get(/api/user/info)this.namedata.namethis.agedata.agethis.sexdata.sex}}})类比 Javastate类似于类的成员变量getters类似于 getter 方法actions类似于普通方法可以修改 state4.2 组合式 API 风格推荐如果习惯 Composition API可以用setup语法import{defineStore}frompiniaimport{ref,computed}fromvueexportconstuseUserStoredefineStore(user,(){// state用 ref 包装constnameref()constageref(0)consttokenref()// getters用 computedconstisLogincomputed(()!!token.value)// actions普通函数functionsetToken(newToken:string){token.valuenewToken}functionclearToken(){token.value}asyncfunctionfetchUserInfo(){constdataawaitrequest.get(/api/user/info)name.valuedata.name age.valuedata.age}// 返回需要暴露的内容return{name,age,token,isLogin,setToken,clearToken,fetchUserInfo}})两种风格对比特性Options API 风格Composition API 风格语法类似 Vuex更灵活符合 Vue3 风格复杂度简单适中推荐场景简单 Store复杂逻辑、需要组合其他 Hook五、使用 Store5.1 在组件中使用script setup langts import { useUserStore } from /stores/user const userStore useUserStore() // 读取 state console.log(userStore.name) console.log(userStore.token) // 读取 getters console.log(userStore.isLogin) // 调用 actions userStore.setToken(xxx) userStore.fetchUserInfo() /script template div p用户名{{ userStore.name }}/p p v-ifuserStore.isLogin已登录/p button clickuserStore.clearToken退出登录/button /div /template5.2 解构 Store直接解构会失去响应式需要用storeToRefsscript setup langts import { storeToRefs } from pinia import { useUserStore } from /stores/user const userStore useUserStore() // ❌ 错误失去响应式 const { name, age } userStore // ✅ 正确保持响应式 const { name, age, isLogin } storeToRefs(userStore) // actions 不需要 storeToRefs它们本身就是函数 const { setToken, fetchUserInfo } userStore /script template p用户名{{ name }}/p p年龄{{ age }}/p /template5.3 直接修改 Statescript setup langts import { useUserStore } from /stores/user const userStore useUserStore() // 方式1直接修改 userStore.name 张三 // 方式2批量修改$patch userStore.$patch({ name: 张三, age: 18 }) // 方式3$patch 函数式 userStore.$patch((state) { state.name 张三 state.age 18 }) // 方式4替换整个 state userStore.$reset() // 重置为初始值 /script方法说明store.xxx value直接修改单个属性store.$patch(object)批量修改store.$patch(function)批量修改函数式store.$reset()重置为初始值推荐简单修改直接赋值复杂修改用$patch。5.4 订阅 State 变化script setup langts import { useUserStore } from /stores/user const userStore useUserStore() // 监听 state 变化 userStore.$subscribe((mutation, state) { console.log(变化类型:, mutation.type) // direct | patch object | patch function console.log(新状态:, state) // 持久化到 localStorage localStorage.setItem(user, JSON.stringify(state)) }) /script六、实战案例用户认证6.1 用户 Storeimport{defineStore}frompiniaimport{ref,computed}fromvueimportrequestfrom/api/requestexportconstuseUserStoredefineStore(user,(){consttokenref(localStorage.getItem(token)||)constnameref()constroleref()constisLogincomputed(()!!token.value)asyncfunctionlogin(username:string,password:string){constdataawaitrequest.post(/api/login,{username,password})token.valuedata.token name.valuedata.name role.valuedata.role localStorage.setItem(token,data.token)}asyncfunctionfetchUserInfo(){if(!token.value)returnconstdataawaitrequest.get(/api/user/info)name.valuedata.name role.valuedata.role}functionlogout(){token.valuename.valuerole.valuelocalStorage.removeItem(token)}return{token,name,role,isLogin,login,logout,fetchUserInfo}})6.2 登录页面script setup langts import { ref } from vue import { useRouter } from vue-router import { ElMessage } from element-plus import { useUserStore } from /stores/user const router useRouter() const userStore useUserStore() const form ref({ username: , password: }) async function handleLogin() { try { await userStore.login(form.value.username, form.value.password) ElMessage.success(登录成功) router.push(/) } catch (error) { ElMessage.error(登录失败) } } /script template div classlogin h2登录/h2 el-form el-form-item el-input v-modelform.username placeholder用户名 / /el-form-item el-form-item el-input v-modelform.password typepassword placeholder密码 / /el-form-item el-button typeprimary clickhandleLogin登录/el-button /el-form /div /template6.3 布局组件显示用户信息script setup langts import { onMounted } from vue import { useRouter } from vue-router import { useUserStore } from /stores/user const router useRouter() const userStore useUserStore() onMounted(() { userStore.fetchUserInfo() }) function handleLogout() { userStore.logout() router.push(/login) } /script template header classheader div classlogo学生管理系统/div div classuser-info span{{ userStore.name }}/span span classrole{{ userStore.role }}/span button clickhandleLogout退出/button /div /header /template6.4 路由守卫使用 Storeimport{useUserStore}from/stores/userrouter.beforeEach((to,from,next){constuserStoreuseUserStore()if(to.meta.requiresAuth!userStore.isLogin){next(/login)}else{next()}})七、多个 Store实际项目会有多个 Store按功能划分src/stores/ ├── user.ts # 用户相关 ├── student.ts # 学生相关 └── app.ts # 应用配置主题、语言等7.1 学生 Storeimport{defineStore}frompiniaimport{ref}fromvueimportrequestfrom/api/requestexportconstuseStudentStoredefineStore(student,(){conststudentsrefStudent[]([])consttotalref(0)constloadingref(false)asyncfunctionfetchStudents(params:QueryParams){loading.valuetruetry{constdataawaitrequest.get(/api/students/page,{params})students.valuedata.list total.valuedata.total}finally{loading.valuefalse}}asyncfunctiondeleteStudent(id:number){awaitrequest.delete(/api/students/${id})// 刷新列表awaitfetchStudents({page:1,size:10})}return{students,total,loading,fetchStudents,deleteStudent}})7.2 在组件中使用多个 Storescript setup langts import { onMounted } from vue import { useUserStore } from /stores/user import { useStudentStore } from /stores/student const userStore useUserStore() const studentStore useStudentStore() onMounted(() { studentStore.fetchStudents({ page: 1, size: 10 }) }) /script template div p当前用户{{ userStore.name }}/p el-table :datastudentStore.students v-loadingstudentStore.loading !-- ... -- /el-table /div /template八、Pinia 持久化默认情况下Pinia 的数据保存在内存中刷新页面会丢失。可以通过插件实现持久化。8.1 安装插件npminstallpinia-plugin-persistedstate8.2 配置插件import{createApp}fromvueimport{createPinia}frompiniaimportpiniaPluginPersistedstatefrompinia-plugin-persistedstateimportAppfrom./App.vueconstpiniacreatePinia()pinia.use(piniaPluginPersistedstate)constappcreateApp(App)app.use(pinia)app.mount(#app)8.3 在 Store 中启用持久化exportconstuseUserStoredefineStore(user,{state:()({token:,name:}),// 启用持久化persist:true})或者自定义持久化配置exportconstuseUserStoredefineStore(user,{state:()({token:,name:,role:}),persist:{key:my-user-store,// 存储 keystorage:localStorage,// 存储方式localStorage 或 sessionStoragepaths:[token,name]// 只持久化部分字段}})九、Pinia vs 直接使用 localStorage维度PinialocalStorage响应式✅ 自动更新❌ 需要手动监听类型安全✅ TypeScript 支持❌ 纯字符串调试✅ Vue DevTools 支持❌ 不支持持久化需要插件✅ 天然支持适用场景运行时状态长期存储推荐运行时状态用 Pinia需要持久化时配合插件使用。十、总结本文系统讲解了 Pinia 状态管理概念作用关键点Store管理共享数据defineStore定义state数据本身用ref包装Composition APIgetters计算属性用computedactions操作方法普通函数可修改 statestoreToRefs解构保持响应式只用于 state 和 getters最佳实践每个 Store 独立文件按功能划分复杂 Store 使用 Composition API 风格需要持久化时使用pinia-plugin-persistedstate解构 Store 时用storeToRefs保持响应式Vue3 学习路径总结通过这五篇博客我们已经系统掌握了 Vue3 的核心知识序号博客核心内容1Vue3入门响应式数据与数据绑定环境搭建、ref/reactive、数据绑定、计算属性、条件/列表渲染2与后端交互axios与请求封装axios 基础、拦截器、环境变量、vue-request3Element Plus实战快速构建增删改查表格、分页、表单、校验、子组件通信4vue-router单页面应用路由管理路由配置、嵌套路由、路由守卫5pinia状态管理跨组件数据共享Store 定义与使用、持久化下一步学习建议TypeScript 进阶泛型约束、类型体操、工具类型Vue3 进阶自定义 Hook、指令、插件工程化Vite 配置、打包优化、CI/CD实战项目完整的后台管理系统作者小张 | 转载请注明出处

相关新闻

2026.7.29:Centos-Stream10使用rpm安装mysql

2026.7.29:Centos-Stream10使用rpm安装mysql

Centos-Stream10使用rpm安装mysql MySQL Download MySQL Comminity Download 1. 下载后解压 tar -xvf mysql-26.7.0-1.el10.x86_64.rpm-bundle.tar

2026/7/30 4:03:34阅读更多 →
全球金融巨头的智慧之选 | 星纵物联助力汇丰银行楼宇智控与客流管理

全球金融巨头的智慧之选 | 星纵物联助力汇丰银行楼宇智控与客流管理

当前,国家先后印发《关于银行业保险业做好金融“五篇大文章”的指导意见》、《银行业保险业数字金融高质量发展实施方案》等政策文件,鼓励和引导银行业保险业加快发展数字金融,充分发挥数字技术和数据要素的双轮驱动作用,赋能金融…

2026/7/30 4:03:34阅读更多 →
AI辅助学术写作:工具、实践与效率提升

AI辅助学术写作:工具、实践与效率提升

1. AI辅助学术写作的时代机遇去年协助一位语言学教授完成专著时,我们团队首次系统性地采用了AI写作工具。原本需要三个月完成的文献综述章节,最终仅用两周就达到了出版社的审稿标准。这个案例让我深刻意识到,学术写作正在经历从"笔耕不辍…

2026/7/30 4:01:33阅读更多 →
Linux 进程调度管理

Linux 进程调度管理

文章目录Linux 进程调度管理进程调度器实时调度器非实时调度器管理进程优先级非实时调度策略nice 值nice 值查看nice 命令renice 命令top 命令实时调度策略Linux 进程调度管理 进程调度器 现代计算机系统中既包含只有单个CPU且任何时候都只能处理单个指令的低端系统到具有几百…

2026/7/30 5:13:50阅读更多 →
芯片存储架构抉择:片上SRAM与CoWoS封装HBM的技术权衡

芯片存储架构抉择:片上SRAM与CoWoS封装HBM的技术权衡

在芯片设计领域,存储架构的选择直接关系到性能、功耗、成本和制造可行性。近期关于谷歌 Frozen v2 芯片可能弃用台积电 CoWoS 先进封装、转向片上 SRAM 的讨论,实际上触及了高性能计算芯片在内存墙挑战下的核心权衡问题。这种转变并非简单的技术路线调整…

2026/7/30 5:13:50阅读更多 →
C/C++实现任意进制转换:从原理到工程实践

C/C++实现任意进制转换:从原理到工程实践

1. 项目缘起:为什么我们还在手动写进制转换? 在编程的日常里,尤其是处理底层数据、网络协议、加密算法或者仅仅是做一些趣味数学题时,进制转换是一个绕不开的基础操作。你可能遇到过需要把一个十六进制的颜色码 #FF5733 转成十进…

2026/7/30 5:13:50阅读更多 →
从零实现C/C++词法分析器:编译原理核心实践指南

从零实现C/C++词法分析器:编译原理核心实践指南

1. 项目概述:从“字符串”到“单词”的翻译官如果你刚开始接触编译原理,可能会觉得这个词法分析器听起来很玄乎。其实,你可以把它想象成一个精通多国语言的翻译官,只不过它翻译的对象是程序员写的源代码。我们写的C/C代码&#xf…

2026/7/30 5:13:50阅读更多 →
Python自动化水文地质计算:承压水抽水试验渗透系数K与影响半径R求解

Python自动化水文地质计算:承压水抽水试验渗透系数K与影响半径R求解

1. 项目概述:从水文地质到Python自动化如果你在水文地质、环境工程或者岩土工程领域工作,那么“抽水试验”和“渗透系数K”这两个词对你来说一定不陌生。这几乎是每个现场工程师和数据分析人员的必修课。传统的做法是什么?现场记录数据&#…

2026/7/30 5:13:50阅读更多 →
FPGA设计核心:硬件并发思维与资源优化实践指南

FPGA设计核心:硬件并发思维与资源优化实践指南

FPGA的设计本质是什么?这个问题看似简单,却触及了硬件工程师从入门到精通必须跨越的核心认知鸿沟。与软件编程不同,FPGA设计不是简单的代码编写,而是硬件电路的时空重构——你需要同时考虑逻辑功能的正确性、时序的稳定性、资源的…

2026/7/30 5:11:49阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/29 9:47:45阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/29 7:00:19阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/29 7:58:51阅读更多 →
3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 [特殊字符]

3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 [特殊字符]

3分钟解锁iOS应用自由:TrollInstallerX让你的iPhone摆脱安装限制 🚀 【免费下载链接】TrollInstallerX A TrollStore installer for iOS 14.0 - 16.6.1 项目地址: https://gitcode.com/gh_mirrors/tr/TrollInstallerX 你是否曾经因为iOS系统的严格…

2026/7/30 0:00:58阅读更多 →
[GESP202606 四级] 扫雷

[GESP202606 四级] 扫雷

B4557 [GESP202606 四级] 扫雷 https://www.luogu.com.cn/problem/B4557 中国计算机学会(CCF)2026年6月C四级讲解——扫雷 https://www.bilibili.com/video/BV1MCMg6AEXR/ B4557 [GESP202606 四级] 扫雷 https://www.bilibili.com/video/BV1ZKTj6ZEVh/ 2…

2026/7/30 0:00:58阅读更多 →
Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南

Windows驱动存储终极清理工具:DriverStoreExplorer完全指南 【免费下载链接】DriverStoreExplorer Driver Store Explorer 项目地址: https://gitcode.com/gh_mirrors/dr/DriverStoreExplorer 您是否曾因Windows系统盘空间不足而烦恼?是否遇到过设…

2026/7/30 0:00:58阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/30 0:27:26阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/30 4:47:18阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/29 14:26:42阅读更多 →