electron+vue3全家桶+vite项目搭建【14】electron多窗口,多语言切换不同步更新问题

news/2024/4/26 17:11:48/文章来源:https://blog.csdn.net/qq_42365534/article/details/130356865

文章目录

    • 引入
    • 问题演示
    • 补充逻辑
      • 注意
      • 封装缓存工具类
      • 补充状态管理
      • 调整多语言初始化
      • 调整多语言切换组件
    • 解决方案
      • 思路整理
      • 渲染进程监听语言切换
      • 主进程创建多语言切换处理
      • 语言切换组件通知主进程语言切换
    • 最终实现效果演示

引入

我们之前在这篇文章中集成了 多语言切换,但随着我们项目越来越复杂,单页面已经无法满足我们的需求,我们需要多个窗口去进行页面展示,此时会暴露很多问题,例如多窗口时,某个窗口切换了语言,其他窗口并不会同步切换

demo项目地址

问题演示

我们在src\components\demo\Index.vue页面中也显示一个多语言文本:

<template><h1>{{ $t(langMap.app_title) }}</h1>
</template>
<script setup lang="ts">import langMap from "@/locales/langMap";
</script>

问题如下:

请添加图片描述

补充逻辑

注意

这里主要是对之前多语言文章的补充,之前写的是个极简的整合,没有考虑很多,如只需要解决多窗口同步问题可直接跳过!!

封装缓存工具类

首先为了记住我们当前所选语言,避免每次重启重新选择,我们将语言持久化在本地,这里参考这篇博客,封装一个缓存工具类:

  • src\utils\cacheUtils.ts
/* localstorage封装,缓存工具类  参考:https://blog.csdn.net/w544924116/article/details/120906411/** key前缀 */
const keyPrefix = 'app_cahce$_';/*** @param value 内容* @param addTime 存入时间* @param expires 有效时间*/
interface valObjParams {value: any;addTime: number;expires: number;
}interface StorageInterface {/*** 设置localStorage* @param value 内容* @param expires 有效时间 单位 s*/set: (key: string, value: any, expires?: number) => void;/** 获取localStorage,会自动转json */get: (key: string) => any;/** 是否含有key */has: (key: string) => boolean;/** 移除 */remove: (key: string) => void;/** 移除全部缓存 */clear: () => void;/** 移除自己前缀的全部缓存 */clearSelf: () => void;
}const storage: StorageInterface = {set: () => {},get: () => '',has: () => false,remove: () => {},clear: () => {},clearSelf: () => {}
};/*** 是否过期*/
const isFresh = (valObj: valObjParams) => {const now = new Date().getTime();return valObj.addTime + valObj.expires >= now;
};/* 给key值添加前缀 */
const addPrefix = (key: string) => {return `${keyPrefix}${key}`;
};/* 加方法 */
const extend = (s: Storage) => {return {set(key: string, value: any, expires?: number) {const skey = addPrefix(key);if (expires) {expires *= 1000; // 将过期时间从微秒转为秒s.setItem(skey,JSON.stringify({value,addTime: new Date().getTime(),expires}));} else {const val = JSON.stringify(value);s.setItem(skey, val);}if (value === undefined || value === null) {s.removeItem(skey);}},get(key: string) {const skey = addPrefix(key);const item = JSON.parse(s.getItem(skey) as any);// 如果有addTime的值,说明设置了失效时间if (item && item.addTime) {if (isFresh(item)) {return item.value;}/* 缓存过期,清除缓存,返回null */s.removeItem(skey);return null;}return item;},has(key: string) {const skey = addPrefix(key);return !!s.getItem(skey);},remove: (key: string) => {const skey = addPrefix(key);s.removeItem(skey);},clear: () => {s.clear();},clearSelf: () => {const arr = Array.from({ length: s.length }, (_, i) => s.key(i)).filter(str => str?.startsWith(keyPrefix));arr.forEach(str => s.removeItem(str as string));}};
};Object.assign(storage, extend(window.localStorage));export default storage;

补充状态管理

我们可以创建一个appStore用来保存整个应用的全局状态:

import { defineStore } from "pinia";
import cacheUtils from "@/utils/cacheUtils";/**应用相关状态管理 */
export const useAppStore = defineStore("appStore", {state() {return {lang: cacheUtils.get("lang") || "zhCn", // app的语言};},
});

调整多语言初始化

  • 补充从缓存中取初始值
  • src\locales\index.ts
import { createI18n } from "vue-i18n";
import en from "./packages/en";
import zhCn from "./packages/zh-cn";
import cacheUtils from "@/utils/cacheUtils";// 初始化i18n
const i18n = createI18n({legacy: false, // 解决Not available in legacy mode报错globalInjection: true, // 全局模式,可以直接使用 $tlocale: cacheUtils.get("lang") || "zhCn", // 从本地缓存中取语言,如果没有 默认为中文fallbackLocale: "en", // set fallback localemessages: {en,zhCn,},
});export default i18n;

调整多语言切换组件

  • 我们在语言切换的时候补充状态更新、缓存设置
import cacheUtils from "@/utils/cacheUtils";
import { useAppStore } from "@/store/modules/appStore";const appStore = useAppStore();// 切换语言
function handleCommand(lang: string) {i18n.locale.value = lang;// 设置缓存的值cacheUtils.set("lang", lang);// 更新全局状态appStore.lang = lang;
}

解决方案

思路整理

我们可以在多语言初始化的时候,让渲染进程监听多语言改变消息,然后主进程创建一个多语言改变handle,然后在语言切换组件中当语言切换时告知主进程语言切换了,并传参当前的语言,接着主进程的handle遍历所有窗口,除通知主进程的窗口外的其他窗口都触发 多语言改变通知,然后窗口自行更新即可。

渲染进程监听语言切换

1.我们在多语言初始化时监听多语言切换通知:

  • 调整src\locales\index.ts代码:
import { useAppStore } from "@/store/modules/appStore";
import { ipcRenderer } from "electron";// ......// 注意,因为 pinia还没初始化就进行取值会有问题,所以这里我们单独暴露一个方法,在 src/main.ts中的 app.mount("#app").$nextTick 中调用
// 初始化语言监听
export function initLangListener() {const appStore = useAppStore();// 监听语言切换时,同步本窗口更新ipcRenderer.on("lang:change", (event, lang: string) => {i18n.global.locale.value = lang;appStore.lang = lang;});
}

2.在src/main.ts中执行初始化监听:

import { initLangListener } from "@/locales";
// .....app.mount("#app").$nextTick(() => {postMessage({ payload: "removeLoading" }, "*");// 初始化多语言切换监听initLangListener();
});

主进程创建多语言切换处理

主进程中创建多语言处理监听,我们在electron\main\index.ts中补充代码:

/**语言修改同步 */
ipcMain.handle("lang:change", (event, lang) => {// 通知所有窗口同步更改语言for (const currentWin of BrowserWindow.getAllWindows()) {const webContentsId = currentWin.webContents.id;// 这里排除掉发送通知的窗口if (webContentsId !== event.sender.id) {currentWin.webContents.send("lang:change", lang);}}
});

语言切换组件通知主进程语言切换

当语言切换时,我们需要通知主进程告诉其他窗口同步修改,所以我们调整 多语言切换组件:

import { ipcRenderer } from 'electron';// 多语言切换时
const handleCommand = (lang: string) => {// ...// 主进程通知其他窗口同步修改语言ipcRenderer.invoke('lang:change', lang);
};

请添加图片描述

最终实现效果演示

请添加图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系dt猫网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【数据挖掘与商务智能决策】第十三章 数据降维之PCA 主成分分析

13.1.2 PCA主成分分析代码实现 1.二维空间降维Python代码实现 import numpy as np X np.array([[1, 1], [2, 2], [3, 3]]) Xarray([[1, 1],[2, 2],[3, 3]])# 也可以通过pandas库来构造数据&#xff0c;效果一样 import pandas as pd X pd.DataFrame([[1, 1], [2, 2], [3, 3…

数字北京城,航行在联通2000M的“大运河”

前故宫博物院院长单霁翔&#xff0c;在《大运河漂来紫禁城》一书中提到过&#xff0c;紫禁城里的石材、木材&#xff0c;甚至每一块砖&#xff0c;都是通过大运河&#xff0c;跋山涉水来到北京的。某种程度上说&#xff0c;北京城的繁荣与这条纵跨南北的“中华大动脉”密不可分…

AntdesignVue 局部全屏后Message、Select 、Modal、Date等组件不显示问题解决方案(最终版)

1、对this.$message.....这种的消息提示组件解决方案如下 在main.js中全局配置消息提示 //单独引用需修改的元素 import { message } from ant-design-vue message.config({maxCount: 1,getContainer:() > document.getElementById(showBigModal) || document.body //父组件…

Android-实现一个登录页面(kotlin)

准备工作 首先&#xff0c;确保你已经安装了 Android Studio。如果还没有安装&#xff0c;请访问 Android Studio 官网 下载并安装。 前提条件 - 安装并配置好 Android Studio Android Studio Electric Eel | 2022.1.1 Patch 2 Build #AI-221.6008.13.2211.9619390, built …

C++(继承中)

目录&#xff1a; 1.基类和派生类对象赋值转换 2.派生类当中的6个默认成员函数 --------------------------------------------------------------------------------------------------------------------------- 派生类对象可以赋值给 基类的对象/基类的指针/基类的引用&am…

Java每日一练(20230425)

目录 1. 乘积最大子数组 &#x1f31f;&#x1f31f; 2. 插入区间 &#x1f31f;&#x1f31f; 3. 删除有序数组中的重复项 II &#x1f31f;&#x1f31f; &#x1f31f; 每日一练刷题专栏 &#x1f31f; Golang每日一练 专栏 Python每日一练 专栏 C/C每日一练 专栏…

CSGO搬砖,每天1-2小时,23年最强副业非它莫属(内附操作流程)

自从我学会了CSGO搬运&#xff0c;我发现生活也有了不小的改变&#xff0c;多了一份收入&#xff0c;生活质量也就提高了一份。 其实刚接触CSGO&#xff0c;我压根就不相信这么能挣钱&#xff0c;因为在印象中&#xff0c;游戏供玩家娱乐竞技的&#xff0c;作为我这种技术渣渣…

直播系统开发中如何优化API接口的并发

概述 在直播系统中&#xff0c;API接口并发的优化是非常重要的&#xff0c;因为它可以提高系统的稳定性和性能。本文将介绍一些优化API接口并发的方法。 理解API接口并发 在直播系统中&#xff0c;API接口是用于处理客户端请求的关键组件。由于许多客户端同时连接到系统&…

HTTP1.1(十二)Cookie的格式与约束

一 Cookie的格式与约束 ① Cookies是什么 1) cookie是我们在前端编程中经常使用的概念2) 使用cookie利用浏览器帮助我们保存客户的相关状态信息,保存用户已经做了什么事情3) 重点和难点[1]、cookie的工作原理[2]、cookie的限制是什么[3]、session又是怎样与cookie关联起来 …

90年三本程序员,8年5跳,年薪4万变92万……

很多时候&#xff0c;虽然跳槽可能带来降薪的结果&#xff0c;但依然有很多人认为跳槽可以涨薪。近日&#xff0c;看到一则帖子。 发帖的楼主表示&#xff0c;自己8年5跳&#xff0c;年薪4万到92万&#xff0c;现在环沪上海各一套房&#xff0c;再干5年码农&#xff0c;就可以…

【Vue】学习笔记-初始化脚手架

初始化脚手架 初始化脚手架说明具体步骤脚手架文件结构 初始化脚手架 说明 Vue脚手架是vue官方提供的标准化开发工具&#xff08;开发平台&#xff09;最新版本是4.x文档Vue CLI 具体步骤 如果下载缓慢请配置npm淘宝镜像 npm config set registry http://registry.npm.taoba…

【移动端网页布局】流式布局案例 ② ( 实现顶部固定定位提示栏 | 布局元素百分比设置 | 列表样式设置 | 默认样式设置 )

文章目录 一、样式测量及核心要点1、样式测量2、高度设定3、列表项设置4、设置每个元素的百分比宽度5、设置图像宽度 二、核心代码编写1、HTML 标签结构2、CSS 样式3、展示效果 三、完整代码示例1、HTML 标签结构2、CSS 样式3、展示效果 一、样式测量及核心要点 1、样式测量 京…

【ChatGPT】如何让 ChatGPT 不再频繁报错,获取更加稳定的体验?

文章目录 一、问题描述二、方案1&#xff1a;使用 OpenAI API Key 来访问 ChatGPT三、方案2&#xff1a;安装 Chrome 插件3.1 介绍3.2 安装步骤3.2.1 插件 & 脚本安装3.2.2 解读功能 一、问题描述 最近一段时间&#xff0c;相信大家都发现了 ChatGPT 一个问题&#xff0c;…

Unity音量滑块沿弧形移动

一、音量滑块的移动 1、滑块在滑动的时候&#xff0c;其运动轨迹沿着大圆的弧边展开 2、滑块不能无限滑动&#xff0c;而是两端各有一个挡块&#xff0c;移动到挡块位置&#xff0c;则不能往下移动&#xff0c;但可以折回 3、鼠标悬停滑块时&#xff0c;给出音量值和操作提示 …

前端 百度地图绘制路线加上图片

使用百度官方示例的方法根据起终点经纬度查询驾车路线但是只是一个线路 <template><div class"transportInfo"><div id"mapcontainer" class"map">11</div><div class"collapse"><el-collapse v-mo…

克隆Linux系统(centos)

克隆前得保证你有一台Linux系统的虚拟机了。 如果没有&#xff0c;可以参考这篇文章&#xff1a; 安装VMware虚拟机、Linux系统&#xff08;CentOS7&#xff09;_何苏三月的博客-CSDN博客 按照示意图一步一步执行即可。 克隆前先关闭运行的虚拟机系统。 然后右键已安装的虚拟…

【图像抠图】【深度学习】Ubuntu18.04下GFM官方代码Pytorch实现

【图像抠图】【深度学习】Ubuntu18.04下GFM官方代码Pytorch实现 提示:最近开始在【图像抠图】方面进行研究,记录相关知识点,分享学习中遇到的问题已经解决的方法。 文章目录 【图像抠图】【深度学习】Ubuntu18.04下GFM官方代码Pytorch实现前言数据集说明1.AM-2k【自然动物】2.B…

Ubuntu更新软件下载更新与移除

目录 一、更新软件源 二、下载与安装软件 三、如何移除软件 四、Ubuntu商店下载软件 一、更新软件源 更新Ubuntu软件源的操作步骤&#xff0c;更新软件源的目的就是&#xff0c;将在Ubuntu官网的软件源更改到本地&#xff0c;也就是国内的软件源&#xff0c;这样的话下载安…

HTML+CSS+JS 学习笔记(三)———Javascript(下)

&#x1f331;博客主页&#xff1a;大寄一场. &#x1f331;系列专栏&#xff1a;前端 &#x1f331;往期回顾&#xff1a;HTMLCSSJS 学习笔记&#xff08;三&#xff09;———Javascript(上) &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注 目录 JavaScrip…

ES6 新特性的let--const 解构赋值--模板字符串--对象相关新特性--箭头函数--综合代码示例

目录 ES6 新特性 ES6 基本介绍 ES6 是什么? let 声明变量 演示 let 的基本使用 注意事项和使用细节 代码演示 : const 声明常量/只读变量 应用实例 注意事项和使用细节 解构赋值 基本介绍 应用实例-数组解构 应用实例-对象解构 模板字符串 基本介绍 应用实例…