1:Pinia 西班牙语菠萝1.1:Pinia是什么Pinia 是Vue 官方新一代状态统一管理库当数据需要在多个不相关的组件间共享的时候需要使用Pinia类似 Redis 集中缓存。专门为vue2和vue3设计是Vuex 的替代方案。Vue 3 官方已推荐新项目直接使用 Pinia不再主推 Vuex。我们在上一章节的路由器中学习了组件之间传递数据比如多层嵌套、兄弟组件、跨页面路由之间数据传递会非常麻烦。很麻烦但是pinia可以完美的结局这个问题 Pinia把公共数据放到全局仓库 (store)任意组件都可以直接读取、修改。F5 刷新页面Pinia 清空前端重新请求接口再回填 Pinia。补充如果想让 Pinia 拥有类似 redis “持久化” 效果前端可以搭配pinia‑plugin‑persistedstate把数据存到浏览器localStorage。localStorage 相当于浏览器本地小磁盘但依然只属于这台电脑这个浏览器别的设备访问不到和后端 Redis 不是一回事。1.2:有什么作用管理跨组件共享全局状态场景举例工业后台 / MES 系统经常用到用户登录信息、token、角色权限、菜单列表页面全局配置、筛选条件缓存多个页面共享的设备列表、工单筛选参数弹窗全局状态、消息通知如果不用状态库组件之间多层传参props 层层传递代码耦合严重 使用 Pinia任意组件直接读取 / 修改全局状态1.3:Pinia 对比 Vuex 核心优势面试必说移除了 MutationVuex修改 state 必须走 mutation同步、action 处理异步模板代码繁琐 Pinia可以直接修改 state异步逻辑写在 action 里结构简单。没有嵌套 modulesVuex 模块嵌套store.user.token Pinia 每个 store 是独立文件扁平结构导入即用不用命名空间 namespaced。原生 TypeScript 支持极好类型自动推导不需要额外复杂类型声明非常适合script setup TS 项目。代码更简洁样板代码极少不需要commit、dispatch降低学习成本。支持组件外部调用 store路由守卫、axios 拦截器里可以直接引入 store 操作状态Vuex 也能实现但 Pinia 更顺畅。Devtools 调试友好支持时间旅行调试。1.4:Pinia的核心状态Pinia 三大核心概念state状态存放共享数据等同于 Vuex 的 stategettters派生状态相当于计算属性有缓存actions修改状态方法支持同步、异步替代 Vuex mutation action2:实战开始2.1:使用pinia之前组件count.vuetemplate div h1pinia的person组件/h1 h2计数器{{ count }}/h2 名字input typetext v-modelname{{ name }} hr !-- v-model双向数据绑定。影响value属性 -- select v-model.numbern option value11/option option value22/option option value33/option /select button clickadd数字/button button clickminus-数字/button /div /template script setup langts import { ref } from vue; let name ref(张三); console.log(name); // 计数器方法 let count ref(0); let n ref(1); function add() { count.value n.value; } function minus() { count.value - n.value; } /script style/style2.2:使用pinia做状态集中管理1:首先安装pinianpm install pinia2:在main.ts中使用piniaimport { createApp } from vue import { createPinia } from pinia import App from ./App.vue const app createApp(App) //创建pinia const pinia createPinia() //使用pinia app.use(pinia) app.mount(#app)2.3:新建store下的count.ts 操作piniaimport { defineStore } from pinia; //定义仓库 const userCountStore defineStore(count, { //状态 state存放共享数据等同于 Vuex 的 state state() { //返回数据 return { name:张三, count: 0, n: 1, }; }, // Actions修改状态的方法支持同步/异步替代Vuex mutationaction actions: { add2():void { this.count this.n; }, minus2() { this.count - this.n; }, // 异步示例 async changeName(newName: string) { // 可以在这里请求后端接口 this.name newName; }, }, }); //导出仓库 默认单利多组件共享 //export default userCountStore; export { userCountStore };2.4:count.vue组件使用piniatemplate div h1pinia的person组件/h1 h2计数器{{ count }}/h2 名字input typetext v-modelname{{ name }} hr !-- v-model双向数据绑定。影响value属性 -- select v-model.numbern option value11/option option value22/option option value33/option /select button clickadd数字/button button clickminus-数字/button hr h1使用pinia/h1 h2计数器{{ countStore.count }}/h2 !-- v-model双向数据绑定。影响value属性 -- select v-model.numbercountStore.n option value11/option option value22/option option value33/option /select button clickadd1数字/button button clickminus1-数字/button hr button clickadd11数字/button button clickminus11-数字/button hr /div /template script setup langts import { ref } from vue; import { userCountStore } from ../store/count let name ref(张三); console.log(name); //1:不实用pinia 计数器方法 let count ref(0); let n ref(1); function add() { count.value n.value; } function minus() { count.value - n.value; } //2:使用pinia, 得到单利的countStore let countStore userCountStore() function add1() { countStore.count countStore.n; } function minus1() { countStore.count - countStore.n; } function add11() { //通过仓库调用方法 countStore.add2(); } function minus11() { //通过仓库调用方法 countStore.minus2(); } /script style/style2.5:storeToRefsstoreToRefs是 Pinia 提供的工具函数专门用来安全解构 Store 中的 state、getter保证解构出来的变量依旧保留响应式。template div h1pinia的person组件/h1 h2计数器{{ count }}/h2 名字input typetext v-modelname{{ name }} hr !-- v-model双向数据绑定。影响value属性 select v-model.numbern option value11/option option value22/option option value33/option /select button clickadd数字/button button clickminus-数字/button -- hr h1使用pinia/h1 h2计数器{{ count }}/h2 !-- v-model双向数据绑定。影响value属性 -- select v-model.numbern option value11/option option value22/option option value33/option /select button clickadd1数字/button button clickminus1-数字/button hr button clickadd11数字/button button clickcountStore.minus2-数字/button hr /div /template script setup langts import { ref } from vue; import { userCountStore } from ../store/count import { storeToRefs } from pinia; let name ref(张三); console.log(name); // //1:不实用pinia 计数器方法 // let count ref(0); // let n ref(1); // function add() { // count.value n.value; // } // function minus() { // count.value - n.value; // } //2:使用pinia, 得到单利的countStore let countStore userCountStore() //storeToRefs结构才能响应式 let {count,n}storeToRefs(countStore); //这两个对象也有了响应式 function add1() { countStore.count countStore.n; } function minus1() { countStore.count - countStore.n; } function add11() { //通过仓库调用方法 countStore.add2(); } function minus11() { //通过仓库调用方法 countStore.minus2(); } /script style/style2.6:pinia持久话因为页面刷新数据会丢失1:安装持久化插件npm install pinia-plugin-persistedstate2:main.ts 注册插件import piniaPluginPersistedstate from pinia-plugin-persistedstate const pinia createPinia() pinia.use(piniaPluginPersistedstate)3:仓库开启持久化export const usePersonStore defineStore(person, { state: () ({...}), getters:{}, actions:{}, persist: true // 开启持久化 })3:案例