当前位置: 首页 > news >正文

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];}}
}
http://www.lryc.cn/news/65489.html

相关文章:

  • java基础入门-05-【面向对象进阶(static继承)】
  • day12 IP协议与ethernet协议
  • 蓝牙耳机哪款性价比高?2023蓝牙耳机性价比排行
  • 关于C语言的一些笔记
  • 【Python入门知识】NumPy数组迭代及连接
  • 我们公司的面试,有点不一样!
  • C++之初识STL—vector
  • 资讯汇总230503
  • C++之编程规范
  • ChatGPT做PPT方案,10组提示词方案!
  • 分布式夺命12连问
  • sourceTree离线环境部署
  • 6.1.1 图:基本概念
  • SlickEdit for Windows and Linux crack
  • ChatGPT实现stackoverflow 解释
  • 第五章 作业(123)【编译原理】
  • 基于Vue的个性化网络学习笔记系统
  • 如何搭建一个HTTP实验环境
  • Electron 环境搭建
  • 农机电招平台~java
  • springboot+vue体质测试数据分析及可视化设计(源码+文档)
  • thinkphp+vue+html高校固定资产管理系统维修 租借4h80u
  • 【学习笔记】「北大集训 2021」经典游戏
  • 优惠卷秒杀功能、全局唯一ID、乐观锁解决超卖问题、悲观锁实现一人一单、集群下锁失效问题
  • Nest的基本概念,以及如何使用Nest CLI来构建一个简单的Web应用程序
  • 15个创新世界119座城:1~10章音频
  • AI面试必刷算法题 附答案和解析 --持续更新中
  • 聊一聊 GDB 调试程序时的几个实用命令
  • MySQL驱动对MYSQL进行update操作时返回值注意UseAffectedRows
  • OpenCV-Python图像几何变换