electron+vue3全家桶+vite项目搭建【17】pinia状态持久化
文章目录
- 引入
- 问题演示
- 实现效果展示、
- 实现步骤
- 1.封装状态初始化函数
- 2.封装状态更新同步函数
- 3.完整代码
引入
上一篇文章我们已经实现了electron多窗口中,pinia的状态同步,但你会发现,如果我们在一个窗口里面修改了状态,然后再打开另一个窗口,此时窗口的状态并没有同步,所以我们需要对pinia的状态进行持久化处理,并在页面初始化时取到本地缓存的状态。
demo项目地址
问题演示
如下所示,我们先在一个窗口中自增数值,然后再打开另一个窗口,此时窗口中的数值仍然是初始值,只有我们再次点击增加时,才会同步【因为我们上一节实现了pinia多窗口状态同步】
实现效果展示、
实现步骤
1.封装状态初始化函数
我们在src\store\plugins\shareStorePlugin.ts中补充初始化函数
- 当pinia对应的状态对象初始化时,我们将对象的引用传入
- 从本地缓存中取到序列化的store对象,我们将其反序列化后遍历key、value设置store的状态即可
/*** 初始化状态对象* @param store*/
function initStore(store: any) {const cacheKey = STORE_CACHE_KEY_PREFIX + store.$id;// 从本地缓存中读取store的值const stateJsonStr = cacheUtils.get(cacheKey);if (stateJsonStr) {const stateCache = JSON.parse(stateJsonStr);const keys = Object.keys(stateCache);const values = Object.values(stateCache);/// 更新各个key对应的值的状态for (let i = 0; i < keys.length; i++) {store.$state[keys[i]] = values[i];}}
}
2.封装状态更新同步函数
我们在src\store\plugins\shareStorePlugin.ts中补充状态更新同步逻辑
- 之前的主动更新逻辑都是累加版本号、设置缓存,通知更新,我们不妨将这段逻辑抽离
- 将对应的store序列化后存入本地缓存中
/*** 状态更新同步* @param stateJsonStr 序列化的状态修改字符串* @param storeName 修改的状态的名称* @param storeUpdateVersion 状态修改的版本号*/
function updateStoreSync(stateJsonStr: string,storeName: string,storeUpdateVersion: number
) {// 更新本地缓存的store版本号const storeCacheVersionKey = STORE_CACHE_VERSION_KEY_PREFIX + storeName;cacheUtils.set(storeCacheVersionKey, storeUpdateVersion, STORE_CACHE_TIME);// 通知主线程更新ipcRenderer.invoke('pinia-store-change', storeName, stateJsonStr);// 更新本地缓存的storecacheUtils.set(STORE_CACHE_KEY_PREFIX + storeName, stateJsonStr);
}
3.完整代码
我们调整之前的代码,将两个函数嵌入到原来的逻辑之中
src\store\plugins\shareStorePlugin.ts
import { ipcRenderer } from "electron";
import cacheUtils from "@/utils/cacheUtils";
import { PiniaPluginContext } from "pinia";// 预设本地store版本缓存时间为50s 实际开发中可以设置很大,缓存时间的限制,目的是为了让版本归零,避免自增超过上限
const STORE_CACHE_TIME = 50;
// 设置本地store缓存的key
const STORE_CACHE_KEY_PREFIX = "store_";
const STORE_CACHE_VERSION_KEY_PREFIX = STORE_CACHE_KEY_PREFIX + "version_";declare module "pinia" {export interface PiniaCustomProperties {storeUpdateVersion: number; // 标记store变更的版本}
}/**获取本地缓存的store的修改版本 */
function getLocalStoreUpdateVersion(storeCacheKey: string) {let currentStoreUpdateVersion: number = cacheUtils.get(storeCacheKey);// 如果本地没有,就初始化一个if (currentStoreUpdateVersion === null ||currentStoreUpdateVersion === undefined) {currentStoreUpdateVersion = 0;cacheUtils.set(storeCacheKey, currentStoreUpdateVersion, STORE_CACHE_TIME);}return currentStoreUpdateVersion;
}// 处理electron多窗口,pinia共享问题
export function shareStorePlugin({ store }: PiniaPluginContext) {// 初始化本地缓存版本const storeName: string = store.$id;/// 缓存keyconst storeCacheVersionKey = STORE_CACHE_VERSION_KEY_PREFIX + storeName;let currentStoreUpdateVersion: number =getLocalStoreUpdateVersion(storeCacheVersionKey);// 初始化同步store版本store.storeUpdateVersion = currentStoreUpdateVersion;// 初始化storeinitStore(store);// 监听数据变化store.$subscribe(() => {// 获取本地存储的最新状态currentStoreUpdateVersion = cacheUtils.get(storeCacheVersionKey);/// 如果本地缓存过期,则重置一个缓存,并且通知主进程让其他窗口更新状态if (currentStoreUpdateVersion === null ||currentStoreUpdateVersion === undefined) {currentStoreUpdateVersion = 0;store.storeUpdateVersion = currentStoreUpdateVersion;console.log(`主动更新 ${storeName} 的状态`);// 主动更新updateStoreSync(JSON.stringify(store.$state),storeName,store.storeUpdateVersion);} else {// 如果版本一致,则增加版本号,且更新本地存储版本 ,并且通知主线程告知其他窗口同步更新store状态if (store.storeUpdateVersion === currentStoreUpdateVersion) {store.storeUpdateVersion++;console.log(`主动更新 ${storeName} 的状态`);// 主动更新updateStoreSync(JSON.stringify(store.$state),storeName,store.storeUpdateVersion);} else {// 如果当前store的版本大于本地存储的版本,说明本地版本重置了【过期重新创建】,此时重置store的版本// 如果当前store的版本小于本地存储的版本,说明是被动更新引起的state变动回调,此时仅更新版本即可store.storeUpdateVersion = currentStoreUpdateVersion;}}});// 监听数据同步修改ipcRenderer.on("pinia-store-set",(event, targetStoreName: string, jsonStr: string) => {// 监听到状态改变后,同步更新状态if (storeName === targetStoreName) {console.log("被动更新状态:" + storeName);const obj = JSON.parse(jsonStr);const keys = Object.keys(obj);const values = Object.values(obj);/// 更新各个key对应的值的状态for (let i = 0; i < keys.length; i++) {store.$state[keys[i]] = values[i];}}});
}/*** 状态更新同步* @param stateJsonStr 序列化的状态修改字符串* @param storeName 修改的状态的名称* @param storeUpdateVersion 状态修改的版本号*/
function updateStoreSync(stateJsonStr: string,storeName: string,storeUpdateVersion: number
) {// 更新本地缓存的store版本号const storeCacheVersionKey = STORE_CACHE_VERSION_KEY_PREFIX + storeName;cacheUtils.set(storeCacheVersionKey, storeUpdateVersion, STORE_CACHE_TIME);// 通知主线程更新ipcRenderer.invoke("pinia-store-change", storeName, stateJsonStr);// 更新本地缓存的storecacheUtils.set(STORE_CACHE_KEY_PREFIX + storeName, stateJsonStr);
}/*** 初始化状态对象* @param store*/
function initStore(store: any) {const cacheKey = STORE_CACHE_KEY_PREFIX + store.$id;// 从本地缓存中读取store的值const stateJsonStr = cacheUtils.get(cacheKey);if (stateJsonStr) {const stateCache = JSON.parse(stateJsonStr);const keys = Object.keys(stateCache);const values = Object.values(stateCache);/// 更新各个key对应的值的状态for (let i = 0; i < keys.length; i++) {store.$state[keys[i]] = values[i];}}
}
相关文章:

electron+vue3全家桶+vite项目搭建【17】pinia状态持久化
文章目录 引入问题演示实现效果展示、实现步骤1.封装状态初始化函数2.封装状态更新同步函数3.完整代码 引入 上一篇文章我们已经实现了electron多窗口中,pinia的状态同步,但你会发现,如果我们在一个窗口里面修改了状态,然后再打开…...

java基础入门-05-【面向对象进阶(static继承)】
Java基础入门-05-【面向对象进阶(static&继承)】 13、面向对象进阶(static&继承)1.1 如何定义类1.2 如何通过类创建对象1.3 封装1.3.1 封装的步骤1.3.2 封装的步骤实现 1.4 构造方法1.4.1 构造方法的作用1.4.2 构造方法的…...

day12 IP协议与ethernet协议
目录 IP包头 IP网的意义 IP数据报的格式 IP数据报分片 以太网包头(链路层协议) IP包头 IP网的意义 当互联网上的主机进行通信时,就好像在一个网络上通信一样,看不见互联的各具体的网络异构细节; 如果在这种覆盖…...

蓝牙耳机哪款性价比高?2023蓝牙耳机性价比排行
随着蓝牙耳机的使用愈发频繁,蓝牙耳机产品也越来越多,蓝牙耳机的功能、价格、外观设计等都不尽相同。接下来,我来给大家推荐几款性价比高的蓝牙耳机,感兴趣的朋友一起来看看吧。 一、南卡小音舱Lite2蓝牙耳机 参考价:…...

关于C语言的一些笔记
文章目录 May4,2023常量问题基本数据类型补码printf的字符格式控制关于异或、异或的理解赋值运算i和i的区别关系运算符 May5,2023逻辑运算中‘非’的理解逗号运算运算符的优先级问题三目运算 摘自加工于C技能树 May4,2023 常量问题 //定义常量 const float PI; PI…...

【Python入门知识】NumPy数组迭代及连接
前言 嗨喽~大家好呀,这里是魔王呐 ❤ ~! 数组迭代 迭代意味着逐一遍历元素,当我们在 numpy 中处理多维数组时, 可以使用 python 的基本 for 循环来完成此操作。 如果我们对 1-D 数组进行迭代,它将逐一遍历每个元素。 实例 迭…...

我们公司的面试,有点不一样!
我们公司的面试,有点不一样! 朋友们周末愉快,我是鱼皮。因为我很屑,所以大家也可以叫我屑老板。 自从我发了自己创业的文章和视频后,收到了很多小伙伴们的祝福,真心非常感谢! 不得不说&#…...

C++之初识STL—vector
文章目录 STL基本概念使用STL的好处容器vector1.vector容器简介2.vector对象的默认构造函数3.vector对象的带参构造函数4.vector的赋值5.vector的大小6.vector容器的访问方式7.vector的插入 STL基本概念 STL(Standard Template Library,标准模板库)STL 从广义上分为: 容器(con…...
资讯汇总230503
230503 12:21 【放松身心亲近自然 自驾露营成旅游新风尚】今年“五一”假期,我国旅游业的快速恢复催生自驾露营休闲游、短途游、夜游等新型旅游产品提质升级。快速发展的新兴旅游业态,在促进旅游消费、培育绿色健康生活方式等方面发挥了积极作用…...
C++之编程规范
目录 谷歌C风格指南:https://zh-google-styleguide.readthedocs.io/en/latest/google-cpp-styleguide/contents/ 编码规则: • 开闭原则:软件对扩展是开放的,对修改是关闭的 • 防御式编程:简单的说就是程序不能崩溃 •…...

ChatGPT做PPT方案,10组提示词方案!
今天我们要搞定的PPT内容是: 活动类型:节日活动、会员活动、新品活动分析类型:用户分析、新品立项、项目汇报内容类型:内容规划、品牌策划 用到的工具: mindshow 邀请码 6509097ChatGPT传送门(免费使用…...

分布式夺命12连问
分布式理论 1. 说说CAP原则? CAP原则又称CAP定理,指的是在一个分布式系统中,Consistency(一致性)、 Availability(可用性)、Partition tolerance(分区容错性)这3个基本…...

sourceTree离线环境部署
目录 1、下载sourceTree安装包,打开之后弹出注册界面(需要去国外网站注册)2、使用技术手段跳过注册步骤3、打开安装包进行安装 注:建议提前安装好git 1、下载sourceTree安装包,打开之后弹出注册界面(需要去…...

6.1.1 图:基本概念
一,基本概念 1.基本定义 (1)图的定义 顶点集不可以是空集,但边集可以是空集。 (2) 有向图的表示: 圆括号 无向图的表示: 尖括号 简单图、多重图: 简单图:…...

SlickEdit for Windows and Linux crack
SlickEdit for Windows and Linux crack 现在可以在“新建注释”对话框中对颜色进行排序,使调色板中的颜色阵列看起来更符合逻辑。 在拆分或扩展行注释时添加了撤消步骤,这样您只需点击“撤消”一次即可撤消行注释扩展。 已更新VHDL颜色编码,…...

ChatGPT实现stackoverflow 解释
stackoverflow 解释 ChatGPT 公开服务以来,程序员们无疑是最早深入体验和"测试"的一批人。出色的效果也引发了一系列知识产权上的争议。著名的 stackoverflow 网站,就宣布禁止用户使用 ChatGPT 生成的内容来回答问题,一经发现&…...

第五章 作业(123)【编译原理】
第五章 作业【编译原理】 前言推荐第五章 作业123 随堂练习课前热身04-17随堂练习04-17课前热身04-24 最后 前言 2023-5-3 22:12:46 以下内容源自《【编译原理】》 仅供学习交流使用 推荐 第四章 作业(123)【编译原理】 第五章 作业 1 1.令文法G为…...
基于Vue的个性化网络学习笔记系统
1.系统登录:系统登录是用户访问系统的路口,设计了系统登录界面,包括用户名、密码和验证码,然后对登录进来的用户判断身份信息,判断是管理员用户还是普通用户。 2.系统用户管理:不管是…...
如何搭建一个HTTP实验环境
这一讲是“破冰篇”的最后一讲,我会先简单地回顾一下之前的内容,然后在 Windows 系统上实际操作,用几个应用软件搭建出一个“最小化”的 HTTP 实验环境,方便后续的“基础篇”“进阶篇”“安全篇”的学习。 “破冰篇”回顾 HTTP …...
Electron 环境搭建
https://start.spring.io/ 在线数据分析网站 https://tj.aldwx.com/ https://www.spsspro.com/ win10如何分屏 拖到边缘 Electron 环境搭建 https://www.electronjs.org/zh/docs/latest/tutorial/%E6%89%93%E5%8C%85%E6%95%99%E7%A8%8B electron 隐藏菜单 electron 标题栏 设…...
RestClient
什么是RestClient RestClient 是 Elasticsearch 官方提供的 Java 低级 REST 客户端,它允许HTTP与Elasticsearch 集群通信,而无需处理 JSON 序列化/反序列化等底层细节。它是 Elasticsearch Java API 客户端的基础。 RestClient 主要特点 轻量级ÿ…...
Java 8 Stream API 入门到实践详解
一、告别 for 循环! 传统痛点: Java 8 之前,集合操作离不开冗长的 for 循环和匿名类。例如,过滤列表中的偶数: List<Integer> list Arrays.asList(1, 2, 3, 4, 5); List<Integer> evens new ArrayList…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放
简介 前面两期文章我们介绍了I2S的读取和写入,一个是通过INMP441麦克风模块采集音频,一个是通过PCM5102A模块播放音频,那如果我们将两者结合起来,将麦克风采集到的音频通过PCM5102A播放,是不是就可以做一个扩音器了呢…...
TRS收益互换:跨境资本流动的金融创新工具与系统化解决方案
一、TRS收益互换的本质与业务逻辑 (一)概念解析 TRS(Total Return Swap)收益互换是一种金融衍生工具,指交易双方约定在未来一定期限内,基于特定资产或指数的表现进行现金流交换的协议。其核心特征包括&am…...

uniapp微信小程序视频实时流+pc端预览方案
方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度WebSocket图片帧定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐RTMP推流TRTC/即构SDK推流❌ 付费方案 (部分有免费额度&#x…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个生活电费的缴纳和查询小程序
一、项目初始化与配置 1. 创建项目 ohpm init harmony/utility-payment-app 2. 配置权限 // module.json5 {"requestPermissions": [{"name": "ohos.permission.INTERNET"},{"name": "ohos.permission.GET_NETWORK_INFO"…...
Axios请求超时重发机制
Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式: 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

Reasoning over Uncertain Text by Generative Large Language Models
https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829https://ojs.aaai.org/index.php/AAAI/article/view/34674/36829 1. 概述 文本中的不确定性在许多语境中传达,从日常对话到特定领域的文档(例如医学文档)(Heritage 2013;Landmark、Gulbrandsen 和 Svenevei…...

九天毕昇深度学习平台 | 如何安装库?
pip install 库名 -i https://pypi.tuna.tsinghua.edu.cn/simple --user 举个例子: 报错 ModuleNotFoundError: No module named torch 那么我需要安装 torch pip install torch -i https://pypi.tuna.tsinghua.edu.cn/simple --user pip install 库名&#x…...

安宝特方案丨船舶智造的“AR+AI+作业标准化管理解决方案”(装配)
船舶制造装配管理现状:装配工作依赖人工经验,装配工人凭借长期实践积累的操作技巧完成零部件组装。企业通常制定了装配作业指导书,但在实际执行中,工人对指导书的理解和遵循程度参差不齐。 船舶装配过程中的挑战与需求 挑战 (1…...