electron+vue3全家桶+vite项目搭建【28】封装窗口工具类【2】窗口组,维护窗口关系

文章目录

    • 引入
    • 实现效果
    • 思路
    • 主进程模块
    • 渲染进程模块
    • 测试效果

引入

demo项目地址

窗口工具类系列文章:
封装窗口工具类【1】雏形

我们思考一下窗口间的关系,窗口创建和销毁的一些动作,例如父子窗口,窗口组合等等,还有一些窗口只能有一个,而某些窗口可以有很多个,按我们当前的窗口创建逻辑,是无法维护一个很复杂的窗口系统的,这就需要我们引入一个窗口组,里面维护各个窗口之间的关系和状态。

实现效果

  • 没有传入key时,默认用窗口id作为窗口组中元素的key
  • 窗口销毁时,元素正常从窗口组中移除
  • 传入相同的key时,旧窗口被聚焦
    electron窗口工具类【2】窗口组,维护窗口关系

思路

从如下场景出发:

  • 我们希望一个唯一窗口被创建后,当再次执行窗口创建时,只是聚焦旧窗口,而不是重新创建窗口。
  • 如何快速的获取某个已建窗口的 windowId或webContentsId,直接用于窗口间的通信

解决方案:

  • 维护一个窗口组,即一个map集合,key作为窗口的唯一标识,每次创建时必须传入key,新建窗口通过判断key是否已存在来聚焦旧窗口
  • map集合的值存储一个对象,对象内存储窗口的windowId和webContentsId,我们在创建窗口时就已知key,便可以很方便的用其获取webContentsId用于在渲染进程直接与另一个窗口的渲染进程进行通信。

主进程模块

1.补充窗口组元素的声明:

  • electron\electron-env.d.ts
...
/** 一些仅在electron中使用的声明 */
declare global {
  // 窗口组
  interface WindowGroup {
    webContentsId: number; // 窗口的渲染层id
    windowId: number; // 窗口id
  }
}

2.在窗口工具类中补充窗口组属性,并在构造方法中初始化

export class WindowUtils {
  
  group: Map<string, WindowGroup>; // 窗口组 key就是传入的key值,如果没传,则取窗口的id作为key值

  /**
   * 构造方法,初始化属性
   */
  constructor() {
    this.group = new Map();
  }
}

3.在窗口新建的方法中补充逻辑:

  • 创建窗口前补充通过key判断已有窗口则聚焦旧窗口逻辑
  • 窗口创建后,补充逻辑将窗口信息和key添加到窗口组中
  • 并在最后补充窗口的通用事件绑定方法,里面补充窗口关闭时清理掉在窗口组中对应的元素
/**
   * 创建窗口
   * @param windowConfig 窗口创建参数
   */
  createWindows(windowConfig: IWindowConfig): BrowserWindow {
    // 先通过key判断是否已窗口,有则聚焦
    let windowKey = windowConfig.key;
    if (windowKey && windowKey.length > 0) {
      /// 先从窗口组中取出记录
      const wg: WindowGroup = this.group.get(windowKey);
      if (wg) {
        /// 根据记录中的窗口id获取窗口,假如存在该窗口,则聚焦该窗口
        const oldWin = BrowserWindow.fromId(wg.windowId);
        if (oldWin) {
          oldWin.focus();
          return oldWin;
        }
      }
    }

    // 创建窗口对象
    ...

    // 将窗口的关键信息与key关联,存入窗口组中
    windowKey = windowKey || win.id.toString();
    this.group.set(windowKey, {
      windowId: win.id,
      webContentsId: win.webContents.id,
    });

    // 根据当前环境加载页面,并传递参数
  	...

    // 绑定通用窗口事件
    this.bindWindowEvent(win, windowConfig);
    console.log(this.group);
    return win;
  }

  /**
   * 绑定窗口事件
   * @param win 窗口对象
   * @param windowConfig 窗口创建参数
   */
  bindWindowEvent(win: BrowserWindow, windowConfig: IWindowConfig) {
    // 窗口关闭监听,此事件触发时,窗口即将关闭,可以拒绝关闭,此时窗口对象还未销毁
    win.on("close", () => {
      /// 设置窗口透明
      win.setOpacity(0);
      /// 在窗口组中删除
      const key = windowConfig.key || win.id.toString();
      this.group.delete(key);
    });

    // 此事件触发时,窗口已关闭,窗口对象已销毁
    win.on("closed", () => {
      // 在窗口对象被关闭时,取消订阅所有与该窗口相关的事件
      win.removeAllListeners();
      // 引用置空
      win = null;
    });
  }

3.应用启动后的第一个窗口我们把它当做主窗口,也补充个唯一key =>main,方便区分其他窗口

  • electron\main\index.ts
  win = windowUtils.createWindows({
    route:"/",
    key:'main'
  });

渲染进程模块

我们渲染进程创建窗口时传入key

  • src\components\demo\Index.vue
<template>    
	<input v-model="windowKey" placeholder="输入新建窗口的key"/>
</template>
<script setup lang="ts">
 ... 
 const windowKey = ref("");
    ...
  electronUtils.createWindow({
    route: windowPath.value,
    key:windowKey.value,
    param: JSON.stringify({
      message: "向你问个好~~",
    }),
  });
</script>

测试效果

  • 没有传入key时,默认用窗口id作为窗口组中元素的key
  • 窗口销毁时,元素正常从窗口组中移除
  • 传入相同的key时,旧窗口被聚焦
    electron窗口工具类【2】窗口组,维护窗口关系

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

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

相关文章

labview数组精讲

题主经过写文章一段时间的发现,许多同学对该软件的理解和编程能力是不太一样的,有些知识相对一些同学较为简单,但是有些同学提问就比较困难。那么针对这个问题,题主打算出一期说白话系列的专栏,在该栏目中用最通俗的大白话和例子去让大家深刻了解这个软件的功能和摸透他的…

【center-loss 中心损失函数】 原理及程序解释(更新中)

文章目录 前言问题引出open-set问题抛出 解决方法softmax函数、softmax-loss函数解决代码&#xff08;center_loss.py&#xff09;原理程序解释 代码运用 如何梯度更新首先了解一下基本的梯度下降算法然后 补充&#xff1a;外围知识模型 前言 学习一下&#xff1a; 中心损失函…

报错问题解决django.db.utils.OperationalError: (1049, “Unknown database ‘ mxshop‘“)

开发环境&#xff1a;ubuntu22.04 pycharm 功能&#xff1a;django连接使用mysql数据库&#xff0c;各项配置看似正常 报错&#xff1a; django.db.utils.OperationalError: (1049, "Unknown database mxshop") 分析检查原因&#xff1a; Setting的配置文件内&…

分布式版本控制系统 git

学习目标&#xff1a; 提示&#xff1a;了解及 学会使用 git 1、 含义&#xff1a; Git&#xff08;读音为/gɪt/&#xff09;是一个 开源的分布式版本控制系统 &#xff0c;可以有效、高速地处理从很小到非常大的项目版本管理。 git 也是Linus Torvalds为了帮助管理Linux内核…

信号系统之快速傅里叶变换

1 使用复数DFT的实数DFT 本文的主题&#xff0c;如何使用 FFT 计算真正的 DFT&#xff1f; 由于 FFT 是一种用于计算复数 DFT 的算法&#xff0c;因此了解如何将实数 DFT 数据输入和输出复数 DFT 格式非常重要。图 12-1 比较了实数 DFT 和复数 DFT 存储数据的方式。实数 DFT …

VUE3 页面路由 router

VUE3 页面路由 router 1.理解路由流程1.1新建工程1.2 理解路由1.3 结果1.4补充 2.路由传递参数2.1.新建工程2.2.打开项目2.3.新建路由2.4 路由传递参数 3.路由嵌套配置3.1 基础3.2 子二级布局文件3.3 配置子二级路由3.4 父级页面链接路由3.5 结果3.6 细节&#xff1a;子二级目录…

String类的使用

String常用的构造方法 String的源码 内部是一个数组和hash值&#xff0c;涉及到常量池后续补充&#xff08;常量池&#xff1a;存储相同的字符时只会存储一租&#xff09; String的比较 equals()与&#xff1a;String里面为我们提供了许多方法&#xff0c;可直接调用&#xf…

Rocky Linux 运维工具 firewall-cmd

一、firewall-cmd​的简介 ​​firewall-cmd​是基于firewalld的防火墙管理工具。用户可以使用它来配置、监控和管理防火墙规则&#xff0c;包括开放端口、设置服务规则等。 二、firewall-cmd​​的参数说明 序号参数描述1​​–zone指定防火墙区域2–add-portxxx/tcp允许特定…

spring boot3解决跨域的几种方式

⛰️个人主页: 蒾酒 &#x1f525;系列专栏&#xff1a;《spring boot实战》 &#x1f30a;山高路远&#xff0c;行路漫漫&#xff0c;终有归途。 目录 1.前言 2.何为跨域 3.跨域问题出现特征 4.方式一&#xff1a;使用 CrossOrigin 注解 5.方式二&#xff1a;自定义…

erp项目采购模块新增商品,商品价格计算demo

1&#xff1a;因为此前erp项目中的采购模块添加商品&#xff0c;实时计算单个商品预估价格及全部商品总额折磨了我很久&#xff0c;所以今天闲来无事优化一下&#xff0c;使用另一种思维来做一个类似demo&#xff0c;作为此前总结反思 2&#xff1a;原来项目模块是这样的 3&am…

达梦数据库DM8安装与配置

达梦数据库安装与配置 1 安装前准备 1.1 新建 dmdba 用户 创建用户所在的组&#xff0c;命令如下&#xff1a; groupadd dinstall创建用户&#xff0c;命令如下&#xff1a; useradd -g dinstall -m -d /home/dmdba -s /bin/bash dmdba修改用户密码&#xff0c;命令如下&am…

(每日持续更新)jdk api之OutputStreamWriter基础、应用、实战

博主18年的互联网软件开发经验&#xff0c;从一名程序员小白逐步成为了一名架构师&#xff0c;我想通过平台将经验分享给大家&#xff0c;因此博主每天会在各个大牛网站点赞量超高的博客等寻找该技术栈的资料结合自己的经验&#xff0c;晚上进行用心精简、整理、总结、定稿&…

MyBatis 学习(五)之 高级映射

目录 1 association 和 collection 介绍 2 案例分析 3 一对一关联和一对多关联 4 参考文档 1 association 和 collection 介绍 在之前的 SQL 映射文件中提及了 resultMap 元素的 association 和 collection 标签&#xff0c;这两个标签是用来关联查询的&#xff0c;它们的属…

中小企业“数智未来”行动|ZStack Cloud 荣获“推荐方案”奖

2月29日&#xff0c;以“数智未来 共创数字时代新篇章”为主题的中小企业“数智未来”行动在京成功举办&#xff0c;本次活动由中央广播电视总台央视频和中国中小企业协会作为联合观察单位&#xff0c;带来了一系列帮助中小企业成就业务新价值和数智化升级的优秀产品和方案&…

从入门到精通的Android进阶学习笔记整理,你有过迷茫吗

面试题 一般Android面试分为两部分&#xff1a;Java部分和Android部分&#xff0c;下面说一下自己面试过程遇到的一些具体题目和一些相关知识点。 一 JAVA相关 1&#xff09;JAVA基础 1.java基本数据类型有哪些&#xff0c;int&#xff0c; long占几个字节 2. 和 equals有什…

Mint_21.3 drawing-area和goocanvas的FB笔记(二)

一、goocanvas安装 Linux mint 21.3 库中带有 libgoocanvas-2.0-dev, 用sudo apt install libgoocanvas-2.0-dev 安装&#xff0c;安装完成后&#xff0c;检查一个 /usr/lib/x86_64-linux-gnu 下是否有libgoocanvas.so的软件链接。如果没有&#xff0c;或是 .so.x 等类似后面…

QT Widget: 自定义Widget组件及创建和使用动静态库

学习自定义Widget组件&#xff0c;书中的案例&#xff1a; // 自定义QmyBattery组件 // QmyBattery.c #include "qmybattery.h"QmyBattery::QmyBattery(QWidget *parent) : QWidget(parent) {}/** 1.QPainter的viewport()与window()分别代表着物理坐标与逻辑坐标区域…

类加载的基本流程

⭐ 作者&#xff1a;小胡_不糊涂 &#x1f331; 作者主页&#xff1a;小胡_不糊涂的个人主页 &#x1f4c0; 收录专栏&#xff1a;JavaEE &#x1f496; 持续更文&#xff0c;关注博主少走弯路&#xff0c;谢谢大家支持 &#x1f496; 类加载 1. 加载2. 验证3. 准备4. 解析5. 初…

maven项目报错Cannot resolve plugin org.apache.maven.plugins:maven-war-plugin:2.2

如果IDEA整合maven没有问题&#xff0c;还是报这个错误&#xff0c;很大可能是由于在下载过程中存在网络问题&#xff0c;导致文件下载一半而停止&#xff0c;但是已经在仓库中存在这个文件夹&#xff0c;解决方法是删除文件夹重新下载即可。 删除本地仓库下的\org\apache\mav…

Gophish+EwoMail 自建钓鱼服务器

GophishEwoMail 自建钓鱼服务器 文章目录 GophishEwoMail 自建钓鱼服务器1.前提准备2.搭建EwoMail邮件服务器1&#xff09;Centos7 防火墙操作2&#xff09;设置主机名3&#xff09;host配置4&#xff09;安装EwoMail5&#xff09;获取DKIM6&#xff09;端口服务介绍7&#xff…
最新文章