07.整合Pinia

news2024/11/16 9:29:48

1. 前言

PiniaVue 的专属状态管理库,它允许你跨组件或页面共享状态。更加契合 VUE3 组合式 APITS 类型支持。想进一步了解,参考官网:https://pinia.vuejs.org/

如果是使用官方脚手架搭建的工程,选择了 pinia 将会自动帮我们整合好,没有选择也没关系,因为官方都是最简单的引入,
实际使用还是要做一些调整的。对于我来说选择唯一的好处就是不用再 `npm install` 一下了。  
npm install pinia

2. 按模块化定义 store

整合好了之后这里要定义 store, 我理解的 store 就是一个全局的数据仓库,用来存放全局状态的数据,为了便于管理,这里我将按模块进行 store 的定义

在这里插入图片描述

  • 创建 src/stores/index.ts
  • main.ts 里引入
  • modules: 按模块定义对应的 store, userInfoStore.ts 表示用户相关数据存储的仓库

::: info

在引入 pinia 的时候做一些调整,不直接在 main.ts 里引入,这样做的好处在于,之后对于 pinia 集成一些插件,或者做一些其他配置,可以独立出来,不用全部堆积在 main.ts 中

:::

2.1. 定义 store

// userInfoStore.ts
import { defineStore } from 'pinia'

// 你可以对 `defineStore()` 的返回值进行任意命名,但最好使用 store 的名字,同时以 `use` 开头且以 `Store` 结尾。(比如 `useUserStore`,`useCartStore`,`useProductStore`)
// 第一个参数是你的应用中 Store 的唯一 ID。
export const useUserInfoStore = defineStore('userInfo', {
  // 其他配置...
})

2.2. 导出

import { createPinia } from 'pinia'

const store = createPinia()

export default store

2.3. main.ts 中引入

//main.ts
...
// 引入 pinia
import store from './stores'

const app = createApp(App)
app.use(store)
...

3. 使用

// LoginPage.vue
// 获取用户信息缓存仓库
const userInfo = useUserInfoStore()

// 处理登录方法
const handleLogin = async () => {
  // 表单验证
  const valid = await ruleFormRef.value?.validate()
  // 校验不成功直接 return
  if (!valid) {
    return false
  }
  // 校验成功进行后续操作
  // 1.加载 loading
  loading.value = true
  // 2.登录请求 获取token
  userInfo
    .login(loginData)
    .then(() => {
      // 跳转
      router.push('/')
    })
    .catch(() => {
      // 验证失败,做一些其他工作
    })
    .finally(() => {
      // 验证结束,隐藏loading
      loading.value = false
    })
}

userStore处理

import { defineStore } from 'pinia'
import type { LoginData, UserInfo } from '@/types/user'
import { setItem } from '@/utils/storage'
import { TOKEN } from '../constant'
import { login, getUserInfo } from '@/api/user'
export const useUserInfoStore = defineStore('userInfo', {
  state: () => {
    // 用户信息
    return {
      user: {} as UserInfo
    }
  },
  actions: {
    // 登录获取token
    async login(loginForm: LoginData) {
      const token = await login(loginForm)
    },

    // 获取用户信息
    async getUserInfo() {
      this.user = await getUserInfo()
    }
  }
})

至此 pinia 可以正常拿到 token 了。但是不是最终想要的结果,正常逻辑应该是,请求获取 token ,将 token 放入本地缓存,再携带 token 获取用户信息,之后将用户信息缓存到 pinia 中。 接下来完成 localStorage 部分的编码 。

4. 编写 localStorage 工具类

这里就不赘述了,看代码 ,主要就是操作 localStorage,新增,编辑,删除数据。

//  localStoreage 工具类
/**
 * 存储数据
 * @param  key 键 
 * @param  value 值
 */
export const setItem = (key: string, value: any) => {
    // value 分为两种
    // 1.基础类型
    // 2.复杂类型
    if (typeof value === 'object') {
      value = JSON.stringify(value)
    }
    window.localStorage.setItem(key, value)
  }

 /**
 * 获取数据
 * @param key 键
 * @returns value
 */
export const getItem = (key: string): any => {
  try {
    const data = window.localStorage.getItem(key)
    return data != null ? JSON.parse(data) : null
  } catch (err) {
    return window.localStorage.getItem(key)
  }
}

  
  /**
   * 删除指定数据
   * @param key 键
   */
  export const removeItem = (key: string) => {
    window.localStorage.removeItem(key)
  }
  

  /**
   * 删除所有数据
   */
  export const removeAllItem = () => {
    window.localStorage.clear()
  }
  
  • 在获取到 token 后保存
    在这里插入图片描述

  • 请求时携带 token
    在这里插入图片描述

便于测试,在请求完登录接口后,直接获取一下用户信息

5. 测试

登录成功之后可以看到 pinia 里存放的信息,前提是安装了 vue devtools 插件
在这里插入图片描述

localStorage 里也有我们存放的 token 信息

在这里插入图片描述

请求也自动带上了 token

image-20240520104117691

6. pinia持久化

在使用的时候发现 pinia 里存储的用户信息,刷新就没有了,其实这点也可以理解,因为是基于内存的,每个页面都有自己独立的 JavaScript 执行环境和内存空间。当一个页面被加载时,浏览器会为其创建一个全新的 JavaScript 上下文,包括内存空间、变量和对象。这意味着每个页面都有自己的数据存储,并且无法直接访问其他页面的内存空间。

此刻我有个疑惑是,使用 pinia 是不是必须要持久化呢?就比如存储用户基本信息这样的场景,如果不持久化就不满足我想要的效果,总不可能每次都去请求一下用户基础信息。那到底什么样的场景适合直接使用 pinia

我查阅了一些资料,最后得出了一个现阶段我对于 pinia 使用的一个认知。

6.1. 不需要持久化的场景

列举了几个我能想到的场景

  • 实时的数据展示: 比如一个实时聊天页面,或者实时的绘制折线图的场景比如股票价格,这些数据只需要展示当前时刻,以及往后不断积累数据展示,保持当前页面最新,刷新后重新开始。
  • 临时状态:当我们操作页面时,前面的一些状态对于后续操作有影响,例如临时的表单数据或者选项选择,这些状态刷新后不需要保持不变
  • UI 状态: 某些状态可能仅与用户界面相关,例如展开/折叠的面板、选项卡选择或滚动位置。这些状态通常不需要在重新加载应用程序时进行持久化。
  • 临时错误状态:临时错误状态:对于错误信息或警告信息,您可以在需要时存储在状态中,以向用户显示相应的提示。这些错误状态通常不需要在刷新页面时进行持久化。

6.2. 持久化场景

  • 用户认证授权:用户认证授权信息
  • 用户个性化设置:比如语言,主题偏好这些

6.3. 使用 pinia-plugin-persistedstate 持久化

之前我们使用的 LocalStorage 就是一种持久化方案,那么如何将 pinia 的存储也整合上去。 好在官方已经提供了现成的插件,我们直接使用就好,不必自己手动去 setItem(token) 了, 想进一步了解可参考官方文档。https://prazdevs.github.io/pinia-plugin-persistedstate/zh/guide/

  • 安装依赖
npm i pinia-plugin-persistedstate
  • 将插件添加到 pinia 实例上
./stores/index.ts
import { createPinia } from 'pinia'
import piniaPluginPersistedstate from 'pinia-plugin-persistedstate'

const store = createPinia()

store.use(piniaPluginPersistedstate)

export default store
  • 在需要持久化的 store 里开启持久化
import { defineStore } from 'pinia'
import type { LoginData, UserInfo } from '@/types/user'
import { setItem } from '@/utils/storage'
import { TOKEN } from '../constant'
import { login, getUserInfo } from '@/api/user'

export const useUserInfoStore = defineStore('userInfo', {
  state: () => {
    // 用户信息
    return {
      user: {} as UserInfo
    }
  },

  actions: {
    // 登录获取token
    async login(loginForm: LoginData) {
      const token = await login(loginForm)
      setItem(TOKEN, token)
    },

    // 获取用户信息
    async getUserInfo() {
      this.user = await getUserInfo()
    }
  },
  persist: true  // [!code ++]
})
  • 测试

登录成功后刷新,数据不会丢失了,并且可以看到存储在了localStorage

在这里插入图片描述

这里持久化的配置是可以设置的,据我大致了解,存进的 key 值默认取得是 store 定义的 name,默认的是 localStorage 存储,可以换成其他,具体看这里: https://prazdevs.github.io/pinia-plugin-persistedstate/zh/guide/config.html

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

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

相关文章

Git之2.5版本重要特性及用法实例(五十七)

简介: CSDN博客专家、《Android系统多媒体进阶实战》一书作者. 新书发布:《Android系统多媒体进阶实战》🚀 优质专栏: Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏: 多媒体系统工程师系列…

Qt应用的高分辨率适配

背景 工作中需要面对触控大屏的4K分辨率场景,同时也有越来越多人开始使用高分屏,原来多基于1080p分辨率开发的Qt程序无法很好适配更高的分辨率。 没有特意针对高分辨率场景做适配时,Qt应用的表现通常有两种情况: 分辨率高的情况…

六西格玛管理培训公司 谈 故障树分析(Fault Tree Analysis)

故障树分析(Fault Tree Analysis, FTA):一种自顶向下的演绎故障分析工具,其中使用布尔逻辑将一系列较低级别的事件组合起来,用以分析系统的非期望状态。那么,如何使用故障树分析(FTA&#xff09…

集成电路学习:什么是CRC循环冗余校验

一、CRC:循环冗余校验 CRC(Cyclic Redundancy Check),即循环冗余校验,是一种根据网络数据包或计算机文件等数据产生简短固定位数校验码的快速算法。它主要用于检测或校验数据传输或保存后可能出现的错误。CRC利用除法及…

[Labview] 表格改值后单元格编辑功能,更改颜色、字体、颜色等

效果如下所示: 例子中演示了单元格变色,具体需要什么修改,在相同的位置进行操作即可。 检测到[鼠标释放]事件,则记录被选中的单元格。 使用[鼠标按下]事件也可以,不过我个人测试下来,[按下]的判断精准度不…

智能候诊系统 项目源码25287

摘 要 科技进步的飞速发展引起人们日常生活的巨大变化,电子信息技术的飞速发展使得电子信息技术的各个领域的应用水平得到普及和应用。信息时代的到来已成为不可阻挡的时尚潮流,人类发展的历史正进入一个新时代。在现实运用中,应用软件的工作…

万亿低空经济:无人机飞手考证正当时

随着低空经济的不断发展和国家政策的持续推动,无人机行业正迎来前所未有的发展机遇。低空经济作为一种新兴的综合性经济形态,依托低空空域,通过各类有人驾驶和无人驾驶航空器的低空飞行活动,辐射带动相关领域融合发展。这一领域涉…

视频结构化从入门到精通——GPU主要硬件平台介绍

视频结构化主要硬件平台 1. 深度学习中“硬”和“软”的概念 在深度学习中,“硬”和“软”通常用于描述不同的处理方法或策略,尤其是在解码、编码、推理等任务中。它们反映了算法在处理信息时的确定性和灵活性。 软(Soft) 处理…

电子检测报告如何盖骑缝章?

电子检测报告如何盖骑缝章?使用e章宝(易友EU3000智能盖章软件)给电子检测报告盖骑缝章,可以遵循以下步骤进行: 一、准备工作 确保e章宝软件已安装: 在计算机上安装e章宝(易友EU3000智能盖章软件…

小程序页面跳转传url参数被截取问题

跳转时处理 const params {url:hhtp://www.baidu.com?a1}const queryString Object.keys(params).map(key > ${encodeURIComponent(key)}${encodeURIComponent(params[key])}).join(&);wx.navigateTo({url: ../../toPageView/toPageView?${queryString},})webview页…

推荐Windows11中帮助提高远程工作效率的6个最佳工具

序言 由于我们中的许多人都在远程工作,Windows 11附带了一些内置的焦点工具来帮助我们完成工作也就不足为奇了。但是,Windows 11究竟为我们这些想要确保我们真正完成工作的专业人士提供了什么?让我们来看看。 专注期和生产力 Windows 11取消了任务栏上的焦点模式,代之以…

李林880重点题推荐

考研倒计时113天,九月份即将来临,目前大家都处在强化阶段的学习中。虽然每个人的复习进度有所不同,但无论进展如何,我们都要保持良好的心态。进度快的同学要继续稳扎稳打,而进度稍慢的同学也不要焦虑,保持专…

部署 Web 项目到 Linux,可以使他人也访问项目的方法

目录 一、环境配置 二、建构项目并打包 三、上传Jar包到服务器, 并运行 3.1 上传Jar包 3.2 运行 jar 包 3.3 开放端口号 四、其他问题 4.1 运行异常问题 4.2 杀掉进程 五、总结 一、环境配置 如果本地项目是SpringBoot项目,使用的数据库是MySQL&#xff…

C语言基础(二十六)

二叉树节点通常包含三个部分&#xff1a;存储数据的部分、指向左子节点的指针、以及指向右子节点的指针。 测试代码&#xff1a; #include "date.h" #include <stdio.h> #include <stdlib.h> #include <time.h> // 定义二叉树节点的结构&a…

Linux虚拟机搭建K8S环境

文章目录 一、环境准备二、系统初始化三、部署master四、添加node节点五、部署网络六、部署dashboard七、登录dashboard面板 一、环境准备 首先在vmware上新建4台相同配置的虚拟机&#xff0c;除了IP和主机名外&#xff0c;其余配置相同。由于是搭建K8S初始环境&#xff0c;没…

Pyqt5高级技巧:多线程任务、窗体交互、常用控件介绍(含基础Demo)

一、多线程任务和多窗体交互 【main】 import MainForm #import CRUD import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QMessageBoxif __name__ __main__:app QApplication(sys.argv)MainWindow QMainWindow()ui MainForm.Ui_MainWindow()#也可能是Ui…

算法设计与分析:实验三 回溯法——地图填色问题

实验内容与要求&#xff1a; 问题描述&#xff1a; 我们可以将地图转换为平面图&#xff0c;每个地区变成一个节点&#xff0c;相邻地区用边连接&#xff0c;我们要为这个图形的顶点着色&#xff0c;并且两个顶点通过边连接时必须具有不同的颜色。附件是给出的地图数据&#…

如何在 MySQL 中使用 Socket 身份验证 ?

在 MySQL 和 MariaDB 中&#xff0c;可以使用 socket 身份验证&#xff0c;而不是传统的用户名和密码组合。这种方法既安全又方便&#xff0c;因为它使用的是操作系统的用户凭证。 什么是 Socket 身份验证? Socket 身份验证允许使用 Unix 或 Linux 用户凭证连接到数据库&…

NS4892B 蓝牙耳机充电仓-线性锂电池充放电管理 IC

1 特性 充电部分  (0V) 涓流 / 恒流 / 恒压三段式充电  内部设定 300mA 充电电流  线性工作模式充电  内置自动复充功能  内部预设 4.2V 充电浮充电压  内置过温保护 放电部分  同步升压输出 5.1V  放电开关频率 1MHz  放电效率最…

【网络】NAT、代理服务、内网穿透

NAT技术与代理服务 文章目录 1.NAT技术1.1NAT技术背景1.2NAT IP转换过程1.3NAPT1.4NAT技术的缺陷 2.代理服务器3.NAT和代理服务器的区别4.内网穿透 1.NAT技术 NAT&#xff08;Network Address Translation&#xff0c;网络地址转换&#xff09;技术&#xff0c;是解决IP地址不…