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

news2024/11/17 7:27:52

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

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

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

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

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

1 下载 pinia 插件

npm i 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 的一些分享了  也欢迎看到这里的你一起分享学习 共同进步!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/410287.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

微信小程序入门教程 --(保姆级)

一、小程序注册 1、首先&#xff0c;到小程序官网注册自己的小程序账号&#xff0c;以下附有地址和教程&#xff1a; 小程序官网 进入这个地址之后&#xff0c;会看到这样的页面&#xff0c;点击立即注册按钮 2、在接下来的页面&#xff0c;选择小程序 3、然后根据提示完成三…

Web基础 HTML标签 六种超链接标签的使用方式

超链接标签&#xff08;重点&#xff09; 1、链接的语法格式&#xff1a; <a href"跳转目标链接" target"目标窗口的弹出方式"> 文本或图像 </a><a>标签里的a是单词anchor的的缩写&#xff0c;意为:锚。 两个属性的作用如下&#xff…

【前端灵魂脚本语言JavaScript⑤】——JS中数组的使用

&#x1f41a; 作者: 阿伟 &#x1f482; 个人主页: Flyme awei &#x1f40b; 希望大家多多支持&#x1f618;一起进步呀&#xff01; &#x1f4ac; 文章对你有帮助&#x1f449;关注✨点赞&#x1f44d;收藏&#x1f4c2; JavaScript数组的使用 文章目录JavaScript数组的使用…

【Vue2从入门到精通】详解Vue数据双向绑定原理及手动实现双向绑定

文章目录✨什么是数据双向绑定✨数据双向绑定的原理✨Vue数据双向绑定原理✨实现数据双向绑定的步骤✨手动实现自定义组件的双向绑定的步骤✨写在最后✨什么是数据双向绑定 我们先从单向绑定切入单向绑定非常简单&#xff0c;就是把Model绑定到View。 什么是双向绑定呢&#…

基于pytorch+Resnet101加GPT搭建AI玩王者荣耀

本源码模型主要用了SamLynnEvans Transformer 的源码的解码部分。以及pytorch自带的预训练模型"resnet101-5d3b4d8f.pth"本资源整理自网络&#xff0c;源地址&#xff1a;https://github.com/FengQuanLi/ResnetGPT注意运行本代码需要注意以下几点 注意&#xff01;&a…

【Unity】Button基础-按钮更换图片样式

话说&#xff0c;今天修改了一下项目中的内容&#xff0c;发现按钮不怎么好看&#xff0c;想用图片的方式改一改&#xff0c;然后点开Button&#xff0c;忽然发现好多内容都忘记了。。。 Transition&#xff08;过渡方式&#xff09;&#xff1a;按钮在状态改变时自身的过渡方式…

P2E游戏《西游降魔》站在元宇宙风口 打造高效、完整且可持续的GameFi2.0体系

引言&#xff1a;当人类大步迈入元宇宙时代&#xff0c;链上P2E游戏《西游降魔》正与元宇宙生态相伴相生&#xff0c;带领人们开启Play to Earn的变革之旅。 区块链结合游戏组成新的 GameFi 赛道&#xff0c;在 2021 年迎来爆炸式增长。各大公链如&#xff1a;ETH、BSC、OKCha…

【蓝桥杯】X进制减法、贪心思想、小白专用

问题描述&#xff1a; 解题分析&#xff1a; 首先要搞明白 X 进制与 十 进制是如何转换的&#xff0c;以 X 进制321为例 题中说明&#xff0c;3 的进制为8&#xff0c;2的进制为10&#xff0c;1的进制为2 那么开始计算&#xff1a; 1就代表一个1 2的话是十进制&#xff0c…

【论文精读】COLING 2020 -带有对偶关系图注意力网络的事件检测模型

【论文精读】COLING 2020 -带有对偶关系图注意力网络的事件检测模型 【论文原文】&#xff1a;Event Detection with Dual Relational Graph Attention Networks 【作者信息】&#xff1a;Jiaxin Mi and Po Hu and Peng Li 论文&#xff1a;https://aclanthology.org/2022.c…

Spring系列(六) --- SpringBoot 与 Servlet 的比较及 Spring 读取配置文件的方式

SpringSpringBoot VS ServletSpring 读取配置文件的方式yml 和 properties 的区别SpringBoot VS Servlet Spring 读取配置文件的方式 1 Value 注解获取单个配置项 如在 yml 中定义一个 qq 音乐的 token; 然后输出, 如下: 2 针对对象的读取: ConfigurationProperties 在 yml 中…

笔记本电脑连接不上WiFi怎么办?4个实用解决方法!

案例&#xff1a;笔记本电脑连接不上WiFi怎么办 “朋友们&#xff0c;想问问大家知道为什么我的笔记本电脑连接不上WiFi呢&#xff1f;试了好几遍还是无法连接&#xff0c;遇到这种情况我应该怎么解决呢&#xff1f;感谢大家&#xff01;” 在现代生活中&#xff0c;笔记本电…

HTTP协议详解(二)

目录 1.HTTP 响应详解 1.1认识状态码(status code) 1.2 认识响应报头(header) 1.3 认识响应正文(body) 2.构造 HTTP 请求 2.1 通过form表单构造请求 2.2 通过ajax构造请求 2.3 使用第三方工具构造请求 开始之前我们先复习一下http协议格式 1.HTTP 响应详解 我们先抓包…

【JavaScript】四个常用功能/案例:表格排序 | 替换链接 | 倒计时 | 双色球机选一注

CSDN话题挑战赛第2期 参赛话题&#xff1a;学习笔记 &#x1f5a5;️ NodeJS专栏&#xff1a;Node.js从入门到精通 &#x1f5a5;️ 博主的前端之路&#xff08;源创征文一等奖作品&#xff09;&#xff1a;前端之行&#xff0c;任重道远&#xff08;来自大三学长的万字自述&am…

《文章复现》考虑用户舒适度的冷热电多能互补综合能源系统优化调度

说明书 免费&#xff1a;https://download.csdn.net/download/qq_50594161/87625438 MATLAB代码&#xff1a;考虑用户舒适度的冷热电多能互补综合能源系统优化调度 关键词&#xff1a;用户舒适度 综合能源 PMV 优化调度 参考文档&#xff1a;《冷热电气多能互补的微能源网鲁…

点击开关按钮,js实现电灯开关效果

初识js&#xff0c;跟大家分享js实现电灯开关灯效果的具体代码&#xff0c;利用简单的htmljs模拟电灯开关的小案例。 首先进行案例分析&#xff1a; 1.获取图片属性 2.判断变量的值 3.点击时切换图片 通过点击按钮实现电灯开关 以下是两张需要的图片&#xff0c;接下来添加…

vue3路由配置及路由跳转传参

1、安装路由 npm i vue-router 2、编写需要展示的路由 在src目录下创建pages文件夹&#xff0c;里面创建两个vue文件命名为student.vue,person.vue 分别编写两个vue文件 student.vue和person.vue <template>学生 </template><script setup></script…

后端架构token授权认证机制:spring security JSON Web Token(JWT)简例

后端架构token授权认证机制&#xff1a;spring security JSON Web Token&#xff08;JWT&#xff09;简例 在基于token的客户端-服务器端认证授权以前&#xff0c;前端到服务器端的认证-授权通常是基于session&#xff0c;自从token机制出现并流行起来后&#xff0c;基于token…

微信小程序详细登录流程(图解+代码流程)

&#x1f482; 个人网站:【紫陌】【笔记分享网】&#x1f485; 想寻找共同学习交流、共同成长的伙伴&#xff0c;请点击【前端学习交流群】微信小程序的登录和web端的登录有一点是不同的&#xff0c;小程序需要和微信的服务通信验证。1.小程序登录流程官网图官网图地址2.认识op…

【node进阶】深度解析Express框架--路由、中间件

✅ 作者简介&#xff1a;一名普通本科大三的学生&#xff0c;致力于提高前端开发能力 ✨ 个人主页&#xff1a;前端小白在前进的主页 &#x1f525; 系列专栏 &#xff1a; node.js学习专栏 ⭐️ 个人社区 : 个人交流社区 &#x1f340; 学习格言: ☀️ 打不倒你的会使你更强&a…

完全卸载vscode

背景 由于插件崩溃、不正确操作等导致vscode出现异常现象&#xff0c;如&#xff1a;代码高亮失效、无法进行转到定义等&#xff0c;此时的vscode就需要重新完全卸载删除再安装&#xff0c;恢复初始化。 步骤 1、卸载vscode&#xff1a; 任何方法都可以&#xff0c;比如win…