【Vue3】状态仓库持久化

news2025/1/9 17:00:50

前言

由于 vuexpinia 是将数据存储到内存中的,所以刷新页面后数据会丢失。如果想要持久化存储,就需要将数据同步到 WebStorage。可以使用现有的插件或者自己手写一个插件,本文对二者均有介绍。

其中手写插件案例使用两个简单模块,分别为 count++计数器 和 input输入框,演示如何持久化状态仓库。

在这里插入图片描述

vuex

1. 手写插件

自定义一个插件,用于在 组件卸载 时将 state 同步到 WebStorage

store/index.js 使用插件

import Vue from "vue"
import Vuex from "vuex"
import myPlugin from "./plugins/persistent" // 引入自定义插件
import count from "./modules/count"
import text from "./modules/text"

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    count,
    text,
  },
  plugins: [myPlugin], // 使用插件
})

./plugins/persistent.js

const myPlugin = (store) => {
  // 在 store 初始化时调用
  console.log(store)
}

export default myPlugin

查看参数 store,state为当前仓库状态

在这里插入图片描述

考虑到频繁存储对性能的浪费,只需在 beforeunload 时将仓库状态同步到 WebStorage 即可。

const KEY = "VUEX_STORE"

const myPlugin = (store) => {
  // 保存仓库数据到本地
  window.addEventListener("beforeunload", () => {
    localStorage.setItem(KEY, JSON.stringify(store.state))
  })

  // 恢复仓库数据
  try {
    const localState = localStorage.getItem(KEY)
    if (localState) store.replaceState(JSON.parse(localState))
  } catch {
    console.log("数据恢复失败")
  }
}

export default myPlugin

在这里插入图片描述

继续优化,可传入配置项用于自定义key、选择存储localStoragesessionStorage、是否立即同步本地存储

./plugins/persistent.js

const myPlugin = (options) => {
  return (store) => {
    const { key, immediately, storageType } = options
    const KEY = key || "VUEX_STORE"
    const storageMap = {
      sessionStorage: sessionStorage,
      localStorage: localStorage,
    }
    const STORAGE = storageMap[storageType] || localStorage // 默认使用 localStorage

    if (immediately) {
      // 仓库数据实时同步到本地存储
      store.subscribe((mutation, state) => {
        STORAGE.setItem(KEY, JSON.stringify(state))
      })
    } else {
      // 页面刷新时,存储仓库数据
      window.addEventListener("beforeunload", () => {
        STORAGE.setItem(KEY, JSON.stringify(store.state))
      })
    }

    // 恢复仓库数据
    try {
      const localState = STORAGE.getItem(KEY)
      if (localState) store.replaceState(JSON.parse(localState))
    } catch {
      console.log("数据恢复失败")
    }
  }
}

export default myPlugin

使用插件时,传入配置项

plugins: [
  myPlugin({
    key: "vx-store",
    storageType: window.sessionStorage,
    immediately: true,
  }),
], // 使用插件

在这里插入图片描述

2. 使用 vuex-persistedstate 插件

插件地址

下载插件

npm i vuex-persistedstate

store/index.js

// store/index.js
import Vue from "vue"
import Vuex from "vuex"
// import myPlugin from "./plugins/persistent" // 引入自定义插件
import count from "./modules/count"
import text from "./modules/text"

import createPersistedState from "vuex-persistedstate"

Vue.use(Vuex)

export default new Vuex.Store({
  modules: {
    count,
    text,
  },
  plugins: [createPersistedState()], // 使用插件
})

该插件默认会在每次修改后同步到 localStorage,key 为 vuex

在这里插入图片描述

可以手动传入配置项,如使用 sessionStorage、key 为 vx_store

plugins: [
  createPersistedState({
    key: "vx_store", // 存储名称
    storage: window.sessionStorage,
  }),
], // 使用插件

在这里插入图片描述

pinia

1. 手写插件

入口文件,pinia使用插件

import { createApp } from "vue"
import "./style.css"
import App from "./App.vue"
import { createPinia } from "pinia" 
import myPlugin from "@/store/plugins/persistent.js" 

const pinia = createPinia() 
pinia.use(myPlugin) // 使用插件

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

plugins/persistent.js

export default function (context) {
  console.log(context)
}

查看打印,不同于 vuex,pinia 将每个使用的模块分别打印,需要对每一个模块进行处理

在这里插入图片描述

与 vuex 一样,默认只有在页面销毁时同步到本地存储

const KEY_PREFIX = "PINIA-STORE-"

export default function (context) {
  const { store } = context
  const KEY = KEY_PREFIX + store.$id

  // 存
  window.addEventListener("beforeunload", () => {
    localStorage.setItem(KEY, JSON.stringify(store.$state))
  })
  // 取
  try {
    const localState = localStorage.getItem(KEY)
    if (localState) {
      store.$patch(JSON.parse(localState))
    }
  } catch {
    console.log("读取失败")
  }
}

在这里插入图片描述

继续优化,可传入配置项包括自定义key前缀、选择存储localStoragesessionStorage、是否立即同步本地存储

const KEY_PREFIX = "PINIA-STORE-"

export default function createPiniaPlugin(options = {}) {
  // 解构传入的参数
  const {
    keyPrefix = KEY_PREFIX,
    storageType = "localStorage",
    immediately,
  } = options
  const storageMap = {
    localStorage: localStorage,
    sessionStorage: sessionStorage,
  }
  const STORAGE = storageMap[storageType]

  // 返回实际的插件函数
  return (context) => {
    const { store } = context
    const KEY = keyPrefix + store.$id

    if (immediately) {
      // 仓库数据实时同步到本地存储
      store.$subscribe((mutation, state) => {
        STORAGE.setItem(KEY, JSON.stringify(state))
      })
    } else {
      // 页面刷新时,存储仓库数据
      window.addEventListener("beforeunload", () => {
        STORAGE.setItem(KEY, JSON.stringify(store.$state))
      })
    }

    // 取出数据
    try {
      const localState = STORAGE.getItem(KEY)
      if (localState) {
        store.$patch(JSON.parse(localState))
      }
    } catch {
      console.log("读取失败")
    }
  }
}
pinia.use(
  myPlugin({
    keyPrefix: "MY-STORE-", // 自定义的前缀
    storageType: "sessionStorage", // 使用 sessionStorage
    immediately: true,
  })
) // 使用本地持久化插件

在这里插入图片描述

2. 使用 pinia-plugin-persistedstate 插件

官方地址

下载插件

npm i pinia-plugin-persistedstate

使用插件

import piniaPluginPersistedstate from 'pinia-plugin-persistedstate' //引入持久化插件

pinia.use(piniaPluginPersistedstate)

创建 Store 时,将 persist 选项设置为 true,整个 Store 将使用默认持久化配置保存。

默认配置:

  • 使用 localStorage 存储
  • key 为 store.$id
  • 存储整个 state
import { defineStore } from "pinia"

export const useCountStore = defineStore("count", {
  state: () => ({
    count: 0,
  }),
  actions: {
    increment() {
      this.count++
    },
  },
  persist: true, // 默认配置
})

只对 count 这个仓库做了持久化处理,input输入框对应的 text 仓库并没有持久化

在这里插入图片描述

自定义配置项

  • key:自定义key
  • storage:存储方式
  • pick:选择存入哪些字段
import { defineStore } from "pinia"

export const useCountStore = defineStore("count", {
  state: () => ({
    count: 0,
    name: "田本初",
  }),
  actions: {
    increment() {
      this.count++
    },
  },
  persist: {
    key: "PINIA-CountStore",
    storage: sessionStorage, // 存储方式
    pick: ["count"], //指定 state 中哪些数据需要被持久化。[] 表示不持久化任何状态,undefined 或 null 表示持久化整个 state
  },
})

可以发现只有count仓库采用持久化、key为自定义、采用 sessionStorage 存储并且只存入了count

在这里插入图片描述

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

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

相关文章

【PyTorch】图像目标检测

图像目标检测是什么 Object Detection 判断图像中目标的位置 目标检测两要素 分类:分类向量 [p0, …, pn]回归:回归边界框 [x1, y1, x2, y2] 模型如何完成目标检测 将3D张量映射到两个张量 分类张量:shape为 [N, c1]边界框张量&#xf…

【选择”丹摩“深入探索智谱AI的CogVideoX:视频生成的新前沿】

文章目录 一、CogVideoX模型概述二、变革性的3D变分自编码器三、先进的3D旋转位置编码四、端到端的视频理解模型五、丹摩平台的环境配置简单介绍六、开发者的展望示例代码:与CogVideoX的交互 2024年8月6日,智谱AI宣布其开源视频生成模型CogVideoX&#x…

16、斑马设备的ppocer-4进行文字识别和opencv-mobile中文显示

基本思想:手上有个斑马设备,是客户的,简单记录一下开发过程和工程项目,同时记录跟着android小哥学习了很多anroid的知识,转ppocr-4参考之前的ppocr-3转换即可,整个框架仍然使用c++ ncnn jni框架推理和现实,图像库使用opencv-mobile 一、首先转paddle-cor-4 到ncnn的框架…

E34.【C语言】位段练习题

1.题目 分析下列代码中位段在内存中的排布(已知测试平台为VS2022) struct S {int a : 2;int b : 5;int c : 10;int d : 30; };int main() {struct S s { 0 };return 0; } 有关位段的知识点见64.【C语言】再议结构体(下)文 2.提示 VS满足:由低地址向高地址存储,按浪费空间…

新书推荐——《深度学习精粹与PyTorch实践》

深度学习绝非不可窥探的黑箱!深入理解其模型和算法的实际运作机制,是驾驭并优化结果的关键。你无需成为数学专家或资深数据科学家,同样能够掌握深度学习系统内部的工作原理。 本书旨在通过深入浅出的方式,为你揭示这些原理,让你在理解和解释…

C++系列-继承

🌈个人主页:羽晨同学 💫个人格言:“成为自己未来的主人~” 继承的概念和定义 继承是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行拓展,增加功能,这样可以…

SSL VPN | Easyconnect下载安装使用 (详尽)

EasyConnect是一款远程连接工具,为用户提供简便、快捷的远程访问和控制解决方案。 目录 下载 安装 使用 卸载 下载 通过链接进入官网技术支持板块 深信服技术支持-简单、高效、自助化服务 (sangfor.com.cn)https://support.sangfor.com.cn/ 选择软件下载 在安…

获取本函数所在代码域内的所有局部变量和值以字典形式返回locals()

【小白从小学Python、C、Java】 【考研初试复试毕业设计】 【Python基础AI数据分析】 获取本函数所在代码域内的 所有局部变量和值 以字典形式返回 locals() 选择题 关于以下代码输出的结果说法正确的是? a 10 def x(): b 20 print(locals()) print("【执行…

二值图像的面积求取的两种方法及MATLAB实现

一、引言 面积在数字图像处理中经常用到,在MATLAB中,计算二值图像的面积通常可以通过两种主要方法实现:遍历法和直接利用bwarea函数。下面将分别介绍这两种方法的原理和相应的MATLAB代码示例。 二、遍历法计算二值图像面积的原理和MATLAB代码…

护眼落地台灯品牌前十名:十大全网超高热度品牌汇总

十大护眼路灯台灯有哪些?在众多照明灯具产品中,护眼落地台灯能够提供适合多场景、大氛围的舒适照明,对于学生、工作群体来说能够有效的提高光线质量,减少不良光线带来的近视风险。可是市场品牌繁多,很容易选购到劣质的…

golang web笔记-2.请求request

什么是request http消息分为request(请求) 和 response(响应) request:在go中是一个struct,代表了客户段发送的http请求,已可以通过request 的方法访问请求中的cookie、URL、User Agent&#xf…

【论文阅读笔记】TOOD: Task-aligned One-stage Object Detection

论文代码:https://github.com/fcjian/TOOD 文章目录 论文小结论文简介论文方法Task-aligned Head(T-Head)T-Head伪代码解释 Task Alignment Learning(TAL)Task-aligned Sample AssignmentTask-aligned Loss 论文实验消…

STM32F1+HAL库+FreeTOTS学习15——互斥信号量

STM32F1HAL库FreeTOTS学习15——互斥信号量 1. 优先级翻转2. 互斥信号量3. 相关API函数;3.1 互斥信号量创建3.2 获取信号量3.3 释放信号量3.4 删除信号量 4. 操作实验1. 实验内容2. 代码实现3. 运行结果 上期我们介绍了数值信号量。这一期我们来介绍互斥信号量 1. 优…

Hadoop FileSystem Shell 常用操作命令

提示:本文章只总结一下常用的哈,详细的命令大家可以移步官方的文档(链接贴在下面了哈🤣)— HDFS官方命令手册链接。 目录 1. cat 命令:查看 HDFS 文件内容2. put 命令:将本地文件上传到 HDFS3.…

基于VirtualBox和Ubuntu的虚拟环境搭建

VirtualBox简介 VirtualBox 是一款开源虚拟机软件。 是由德国 Innotek 公司开发,由Sun Microsystems公司出品的软件,使用Qt编写,在 Sun 被 Oracle 收购后正式更名成 Oracle VM VirtualBox。简单易用,可虚拟的系统包括Windows&…

浅谈汽车智能座舱如何实现多通道音频

一、引言 随着汽车智能座舱的功能迭代发展,传统的 4 通道、6 通道、8 通道等音响系统难以在满足驾驶场景的需求,未来对于智能座舱音频质量和通道数会越来越高。接下来本文将浅析目前智能座舱如何实现音频功放,以及如何实现多路音频功放方案。…

Library介绍(三)

环境描述 工作条件 一般lib文件里面包含了芯片的工作条件即operation conditions,其指定了工艺(process)、温度(temperature)和电压(voltage),见图1。 其中,process代表了…

10款超好用的图纸加密软件推荐!2024企业图纸加密最佳选择!

在现代企业中,保护知识产权和敏感数据显得尤为重要。尤其是工程设计、建筑图纸等专业文件,若遭到泄露,可能导致巨大的经济损失和竞争优势的丧失。为了帮助企业有效保护图纸,本文将推荐10款超好用的图纸加密软件。 1.安秉图纸加密软…

【CSS in Depth 2 精译_043】6.5 CSS 中的粘性定位技术 + 本章小结

当前内容所在位置(可进入专栏查看其他译好的章节内容) 第一章 层叠、优先级与继承(已完结)第二章 相对单位(已完结)第三章 文档流与盒模型(已完结)第四章 Flexbox 布局(已…

在起草行业标准时,如何确保格式统一?

一、遵循相关规范 1. 严格按照国家有关标准编写规范以及行业特定的标准编写指南进行起草。熟悉并掌握规范中对于标准结构、条款编号、字体字号、图表格式等方面的具体要求。 2. 参考已发布的同行业成熟标准的格式,学习其成功的格式布局和表达形式。 二、建立模板 1…