首页IT科技vue如何实现状态管理(vue3+ts项目里如何使用状态管理pinia以及数据持久化)

vue如何实现状态管理(vue3+ts项目里如何使用状态管理pinia以及数据持久化)

时间2025-05-02 08:40:51分类IT科技浏览3999
导读:我们都知道在vue2项目里搭配状态管理vuex3XX使用,效果极好的。...

我们都知道在vue2项目里搭配状态管理vuex3XX使用           ,效果极好的           。

虽然在vue3项目里                 ,vuex4XX仍能发挥余热     ,但由于缺乏对于ts的支持     ,使得类型推断陷入僵局                 。

所以在vue3+ts的项目里                 ,vuex渐被舍弃           ,pinia取而代之     。(尤雨溪亦力荐之)pinia官网

下面是在vue3 + ts 项目里如何使用 pinia 步骤

这里是如何从零开始由vite构建vue3+ts项目的流程介绍

1 下载 pinia 插件

2 引入和使用插件

main.ts

import { createApp } from vue import ./style.css import App from ./App.vue import router from ./router import elementPlus from element-plus import element-plus/dist/index.css // ① 引入createPinia方法从pinia import { createPinia } from pinia // ② 拿到pinia实例 const pinia = createPinia() const app = createApp(App) //使用pinia app.use(router).use(elementPlus).use(pinia).mount(#app)

3 创建store/home.ts状态管理文件来管理对应页面(home.vue)

store/home.ts

// 每个状态管理文件都要引入此方法 import { defineStore } from pinia // 官方建议取名遵从 useXXXStore 形式 // home 为当前store的唯一标识 类似ID // 取名建议与文件名称一致 便于记忆和管理 // pinia舍弃了冗长的mutations属性 // 以下是pinia的一种写法 因与vuex相似 便于学习和记忆 export const useHomeStore = defineStore(home,{ state:()=>{ return{ num:0 } }, //state也可写成这样 // state:()=>({ // num:0 // }), actions:{ changeNum(){ //这里可以使用this去拿到state里定义的变量 this.num ++ } }, getters:{ // 这里取名不可与state里的变量一致 所以取名getNum getNum:state=>state.num } })

4 在对应页面组件home.vue里使用状态管理文件home.ts

home.vue

<template> <div class="c">this is home page</div> <div class="c"> <p>使用pinia直接改变变量</p> <!-- 3 解构赋值后直接在template模板里调用变量和方法 --> <p>{{ num }}</p> <button @click="changeNum">点击递增</button> </div> </template> <script lang="ts" setup> import { toRefs } from vue // 1 引入 import { useHomeStore } from "../store/home"; // 2 拿到实例 const homeStore = useHomeStore(); // 3 解构里面的变量和方法 toRefs作用是让解构出来的变量具有响应性 const { num,changeNum } = toRefs(homeStore); </script> <style scoped> .c { width: 80%; padding: 20px; margin: 0 auto; border: 1px solid red; } .c>p>span{ color:coral; } </style>

静态展示效果:

点击按钮改变变量效果:

 如果像这样频繁改变变量 官方建议使用 $patch 方法 (官方优化加持)

具体操作如下

home.vue

<template> <div class="c">this is home page</div> <div class="c"> <p>使用pinia直接改变变量</p> <!-- 3 不解构赋值 在template模板里的写法 --> <p>{{ homeStore.num }}</p> <button @click="changeNum">点击递增</button> </div> </template> <script lang="ts" setup> // 1 引入 import { useHomeStore } from "../store/home"; // 2 拿到实例 const homeStore = useHomeStore(); // 频繁改变homeStore里面的变量 建议使用$patch方法 // 一 $patch的对象式写法 // const changeNum = ()=>{ // homeStore.$patch({ // num: ++ homeStore.num // }) // } // 二 $patch的函数式写法 const changeNum = ()=>{ // 这里的state就是home.ts里的state homeStore.$patch((state)=>{ state.num ++ }) } </script> <style scoped> .c { width: 80%; padding: 20px; margin: 0 auto; border: 1px solid red; } .c>p>span{ color:coral; } </style>

效果:

 除了以上定义变量后 让变量自身变化的外 我们也可以在actions里请求接口数据赋值变量

如下

home.ts

// 每个状态管理文件都要引入此方法 import { defineStore } from pinia //引入接口 import { httpPost } from ../request/api // 官方建议取名遵从 useXXXStore 形式 // home 为当前store的唯一标识 类似ID // 取名建议与文件名称一致 便于记忆和管理 // pinia舍弃了冗长的mutations属性 // 以下是pinia的一种写法 因与vuex相似 便于学习和记忆 export const useHomeStore = defineStore(home,{ state:()=>{ return{ num:0, token: } }, //state也可写成这样 // state:()=>({ // num:0 // }), actions:{ changeNum(){ //这里可以使用this去拿到state里定义的变量 下面同理 this.num ++ }, changeToken(){ // ts 实在学的不咋地 这里就先any了 httpPost().then((res:any)=>{ this.token = res.data.data.token }) } }, getters:{ // 这里取名不可与state里的变量一致 所以取名getNum //简写 getNum:state=>state.num, //全写 // getNum:(state)=>{ // return state.num // } getToken:state=>state.token, } })

相应组件页面使用

home.vue

<template> <div class="c">this is home page</div> <div class="c"> <p>使用pinia直接改变变量</p> <!-- 解构赋值后直接在template模板里调用变量和方法 --> <p>{{ num }}</p> <button @click="changeNum">点击递增</button> </div> <div class="c"> <button @click="changeToken">使用pinia请求数据接口赋值token</button> <p>token: <span>{{ token }}</span></p> </div> </template> <script lang="ts" setup> import { toRefs } from vue // 1 引入 import { useHomeStore } from "../store/home"; // 2 拿到实例 const homeStore = useHomeStore(); // 3 解构里面的变量和方法 toRefs作用是让解构出来的变量具有响应性 const { num,changeNum,token,changeToken } = toRefs(homeStore); </script> <style scoped> .c { width: 80%; padding: 20px; margin: 0 auto; border: 1px solid red; } .c>p>span{ color:coral; } </style>

效果:

 pinia 也存在和vuex一样的弊端 就是刷新页面后 数据丢失

我们可以使用 pinia-plugin-persistedstate 插件来完成数据持久化

数据持久化具体步骤

1 下载插件 pinia-plugin-persistedstate

npm i pinia-plugin-persistedstate

2 main.ts引入和使用插件

main.ts

import { createApp } from vue import ./style.css import App from ./App.vue import router from ./router import elementPlus from element-plus import element-plus/dist/index.css // ① 引入createPinia方法从pinia import { createPinia } from pinia // ② 拿到pinia实例 const pinia = createPinia() // 1 引入数据持久化插件 import piniaPluginPersistedstate from pinia-plugin-persistedstate // 2 pinia使用数据持久化插件 pinia.use(piniaPluginPersistedstate) const app = createApp(App) //使用pinia app.use(router).use(elementPlus).use(pinia).mount(#app)

3 对应状态管理文件配置参数(这里以home.ts为例)

home.ts

// 每个状态管理文件都要引入此方法 import { defineStore } from pinia //引入接口 import { httpPost } from ../request/api // 官方建议取名遵从 useXXXStore 形式 // home 为当前store的唯一标识 类似ID // 取名建议与文件名称一致 便于记忆和管理 // pinia舍弃了冗长的mutations属性 // 以下是pinia的一种写法 因与vuex相似 便于学习和记忆 export const useHomeStore = defineStore(home,{ state:()=>{ return{ num:0, token: } }, //state也可写成这样 // state:()=>({ // num:0 // }), actions:{ changeNum(){ //这里可以使用this去拿到state里定义的变量 下面同理 this.num ++ }, changeToken(){ // ts 实在学的不咋地 这里就先any了 httpPost().then((res:any)=>{ this.token = res.data.data.token }) } }, getters:{ // 这里取名不可与state里的变量一致 所以取名getNum //简写 getNum:state=>state.num, //全写 // getNum:(state)=>{ // return state.num // } getToken:state=>state.token, }, //数据持久化配置 这里是当前所有变量都持久化 persist:true })

效果:

 在实际项目里 token持久化是我们所不希望的 那如何只让num这一变量持久化呢

进一步配置参数即可

home.ts

// 每个状态管理文件都要引入此方法 import { defineStore } from pinia //引入接口 import { httpPost } from ../request/api // 官方建议取名遵从 useXXXStore 形式 // home 为当前store的唯一标识 类似ID // 取名建议与文件名称一致 便于记忆和管理 // pinia舍弃了冗长的mutations属性 // 以下是pinia的一种写法 因与vuex相似 便于学习和记忆 export const useHomeStore = defineStore(home,{ state:()=>{ return{ num:0, token: } }, //state也可写成这样 // state:()=>({ // num:0 // }), actions:{ changeNum(){ //这里可以使用this去拿到state里定义的变量 下面同理 this.num ++ }, changeToken(){ // ts 实在学的不咋地 这里就先any了 httpPost().then((res:any)=>{ this.token = res.data.data.token }) } }, getters:{ // 这里取名不可与state里的变量一致 所以取名getNum //简写 getNum:state=>state.num, //全写 // getNum:(state)=>{ // return state.num // } getToken:state=>state.token, }, //数据持久化配置 这里是当前所有变量都持久化 // persist:true //按需配置数据持久化 这里指定变量num保持持久化 persist:{ //默认名称为当前store唯一标识 这里即home key:homeNum, //默认localStorage 本地储存 //这里建议临时储存sessionStorage 也可写成window.sessionStorage storage:sessionStorage, //默认当前store里的所有变量都持久化 paths:[num] } })

效果:

 最后总结一下pinia一些优点

① 舍弃了冗长的 mutations 属性

② 舍弃了模块化 modules 让状态管理更加扁平化

③ 对于 ts 的支持更加友好 支持数据推断

④ 你甚至可以让各个状态管理相互依赖           、嵌套

以上就是我目前在学习 pinia 的一些分享了  也欢迎看到这里的你一起分享学习 共同进步!

声明:本站所有文章     ,如无特殊说明或标注                ,均为本站原创发布     。任何个人或组织           ,在未征得本站同意时,禁止复制                、盗用      、采集           、发布本站内容到任何网站                、书籍等各类媒体平台                 。如若本站内容侵犯了原著者的合法权益                ,可联系我们进行处理           。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
ai自瞄软件(Ai实现FPS游戏自动瞄准 yolov5fps自瞄) win11多桌面切换(windows11怎么创建多个桌面? win11开多个虚拟桌面的技巧)