electron+vue3全家桶+vite项目搭建【27】封装窗口工具类【1】雏形

文章目录

    • 引入
    • 思路
    • 抽出公共声明文件
    • 抽出全局通用数据类型和方法
    • 主进程模块
      • 1.抽离基础常量
      • 2.封装窗口工具类
    • 渲染进程模块
    • 测试结果

引入

demo项目地址

可以看到我们之前在主进程中的逻辑全部都塞到index.ts文件中,包括窗口的一些事件处理,handle监听,协议注册等等,后期维护起来会比较麻烦,我们不妨将其中的功能细分,封装到工具类中。

思路

以新建窗口举例,流程为

  • 主进程ipcMain.handle监听,根据传来的参数构建新窗口
/**
 * 新建一个窗口
 * route=>路由地址  paramJsonStr => 序列化后的参数对象
 */
ipcMain.handle("open-win", (_, route: string, paramJsonStr: string) => {...})
  • 渲染进程调用 ipcRenderer.invoke方法通知主进程创建窗口
/**
 * 新建一个窗口
 * @param path 路由地址
 * @param param 传递的参数
 */
export function openWindow(path: string, param?: Object) {
  ...
  ipcRenderer.invoke("open-win", path, paramJsonStr);
}

可以预见的是,后续窗口的创建逻辑会随着业务逻辑而扩展,例如创建窗口时 指定窗口宽高,标题,背景色等属性,设置窗口透明,事件击穿等等内容,并且多个窗口间的一些交互需要我们去维护一个窗口组信息,记录窗口的id和逻辑上的关联关系等。
所以我们不妨创建一个窗口工具类,专门集成封装窗口相关的方法,属性等

抽出公共声明文件

我们在渲染进程项目模块中的electronUtils和主进程中的窗口工具类中的【handle/on】方法是一一对应的【invoke/send】,传入的参数也是通用的,所以我们不妨抽出一个公共的全局声明文件,用于声明通用的一些参数对象。

1.在全局声明文件中添加通用事件对象的声明

  • types\global.d.ts
/** 一些全局的对象补充声明 */
export {};
declare global {
	...
      // 窗口创建参数规范
  interface IWindowConfig {
    key?: string; // 窗口唯一key,不传则取窗口的id,假如已存在该key则聚焦该窗口
    route?: string; // 窗口路由
    width?: number; // 窗口宽度
    height?: number; // 窗口高度
    param?: string; // 传递参数,新窗口打开时能直接从路由中获取,拼接url传递,推荐只传小数据
  }
}

2.主进程引入全局声明文件

  • electron\electron-env.d.ts
/// <reference types="vite-plugin-electron/electron-env" />

import "../types/global.d.ts";

抽出全局通用数据类型和方法

主进程和渲染进程都会调用相同的事件名称,所以我们不妨定义一个全局的事件枚举类,方便两个进程的代码书写和规范【事件名称应当唯一,否则会重复绑定】。

1.在根目录下创建globel目录,然后分别创建channelEvent.ts和channelEvent.d.ts两个文件 【事件管道枚举和对应的声明文件】

请添加图片描述

  • globel\channelEvent.ts
/**
 * 自定义事件枚举
 */
export enum CustomChannel {
  window_create = "custom_window_create", // 窗口新建事件
  window_move_on = "custom_window_move_on", // 开启窗口移动事件
  window_position_change = "custom_window_position_change", // 修改窗口的位置
}
  • globel\channelEvent.d.ts
// customEvents.d.ts

/**
 * 自定义事件枚举的类型声明
 */
export declare enum CustomChannel {
  window_create = "custom_window_create", // 窗口新建事件
  window_move_on = "custom_window_move_on", // 开启窗口移动事件
  window_position_change = "custom_window_position_change", // 修改窗口的位置
}

2.在根目录下的tsconfig.node.json文件中添加引入

  • tsconfig.node.json
  "include": [...,"globel"]

3.配置别名快速访问

  • vite.config.ts
... 
resolve: {
      alias: {
		...
        "@globel": path.resolve(__dirname, "./globel"),
      },
    },
  • tsconfig.json
{
  "compilerOptions": {
	...
    "paths": {
        ...
      "@globel/*": ["globel/*"],
    },
    "types": ["vite-plugin-svg-icons/client"]
  },

}

主进程模块

1.抽离基础常量

我们将主进程中常用的常量抽离到单独的文件中:

  • electron\main\common\variables.ts
import { join } from 'node:path';

/**
 *公共变量配置
 */
process.env.DIST_ELECTRON = join(__dirname, '..');
process.env.DIST = join(process.env.DIST_ELECTRON, '../dist');
process.env.PUBLIC = process.env.VITE_DEV_SERVER_URL
  ? join(process.env.DIST_ELECTRON, '../public')
  : process.env.DIST;

// 公共变量中存一份SRC的路径,方便取值
process.env.SRC_PATH = join(__dirname, '../../src').split('\\').join('/');

// 预加载文件路径
export const preloadPath = join(__dirname, '../preload/index.js');
// dev环境请求地址
export const url = process.env.VITE_DEV_SERVER_URL;
// 部署环境的html文件路径
export const indexHtmlPath = join(process.env.DIST, 'index.html');
// icon图标地址
export const iconPath = join(process.env.PUBLIC, 'icons/icon.ico');
// app的title,会被index.html中配置的<title>%VITE_APP_TITLE%</title> 覆盖
export const appTitle = "新窗口";
// app在windows上注册表的协议
export const PROTOCOL = 'bcxlelectrondemo';

2.封装窗口工具类

注意:

1.定义默认窗口参数时使用了ts中的联合类型,这样定义的defaultWindowConfig就必须拥有指定的两个类型中的所有属性

2.创建了一个窗口类,并将窗口相关的逻辑封装为窗口类中的成员方法

3.窗口类中定义个一个listen方法,里面放置所有需要与渲染进程交互的handle监听

  • electron\main\windowUtils.ts
import {
  BrowserWindow,
  BrowserWindowConstructorOptions,
  ipcMain,
} from "electron";
import {
  url,
  appTitle,
  preloadPath,
  iconPath,
  indexHtmlPath,
} from "./common/variables";
import { CustomChannel } from "../../globel/channelEvent";

/* ======================= 定义一些窗口工具类中会使用到的常量,以及窗口顶级父类 ========================= */

// 默认窗口参数
export const defaultWindowConfig: BrowserWindowConstructorOptions &
  IWindowConfig = {
  title: appTitle,
  icon: iconPath,
  width: 800,
  height: 600,
  webPreferences: {
    webviewTag: true,
    preload: preloadPath,
    nodeIntegration: true,
    contextIsolation: false,
  },
};

/**
 * 窗口工具类
 */
export class WindowUtils {
  // 事件监听处理
  listen() {
    // 窗口创建监听
    ipcMain.handle(CustomChannel.window_create, (_, opt: IWindowConfig) => {
      this.createWindows(opt);
    });
  }

  /**
   * 创建窗口
   * @param windowConfig 窗口创建参数
   */
  createWindows(windowConfig: IWindowConfig): BrowserWindow {
    // 创建窗口对象
    const win = new BrowserWindow(
      Object.assign({}, defaultWindowConfig, windowConfig)
    );

    // 根据当前环境加载页面,并传递参数
    const param = windowConfig.param
      ? "?urlParamData=" + windowConfig.param
      : "";
    if (process.env.VITE_DEV_SERVER_URL) {
      // 如果是开发环境,则直接访问本地跑起的服务,拼接对应的路由
      win.loadURL(`${url}#${windowConfig.route}${param}`);
    } else {
      // 如果是线上环境,则加载html文件的路径,然后拼接路由
      win.loadFile(indexHtmlPath, { hash: windowConfig.route + param });
    }

    // 绑定通用窗口事件
    return win;
  }
}

接着我们调整index.ts中的创建主窗口的代码:

import {WindowUtils} from './windowUtils'


// 创建窗口工具类
const windowUtils = new WindowUtils();
windowUtils.listen();

...
async function createWindow() {
    ...
    win = windowUtils.createWindows({
        route:"/"
      });
}

对比之前代码,简练了不少

请添加图片描述

渲染进程模块

1.我们调整通用交互工具类,补充新的窗口创建方法

  • src\utils\electronUtils.ts
import { ipcRenderer } from "electron";
import { CustomChannel } from "@globel/channelEvent";
/**
 * 新建一个窗口
 * @param windowConfig
 */
export function createWindow(windowConfig: IWindowConfig) {
  ipcRenderer.invoke(CustomChannel.window_create, windowConfig);
}

2.调整demo代码

  • src\components\demo\Index.vue
 electronUtils.createWindow({
    route: windowPath.value,
    param: JSON.stringify({
      message: "向你问个好~~",
    }),
  });

electron窗口工具类封装

测试结果

能够正常的创建窗口
electron窗口工具类封装测试

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

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

相关文章

docker 容器访问 GPU 资源使用指南

概述 nvidia-docker 和 nvidia-container-runtime 是用于在 NVIDIA GPU 上运行 Docker 容器的两个相关工具。它们的作用是提供 Docker 容器与 GPU 加速硬件的集成支持&#xff0c;使容器中的应用程序能够充分利用 GPU 资源。 nvidia-docker 为了提高 Nvidia GPU 在 docker 中的…

【PX4SimulinkGazebo联合仿真】在Simulink中使用ROS2控制无人机进入Offboard模式起飞悬停并在Gazebo中可视化

在Simulink中使用ROS2控制无人机进入Offboard模式起飞悬停并在Gazebo中可视化 系统架构Matlab官方例程Control a Simulated UAV Using ROS 2 and PX4 Bridge运行所需的环境配置PX4&Simulink&Gazebo联合仿真实现方法建立Simulink模型并完成基本配置整体框架各子系统实现…

C语言编程安全规范

目的 本规范旨在加强编程人员在编程过程中的安全意识,建立编程人员的攻击者思维,养成安全编码的习惯,编写出安全可靠的代码。 2 宏 2.1 用宏定义表达式时,要使用完备的括号 2.2 使用宏时,不允许参数发生变化 3 变量 3.1 所有变量在定义时必须赋初值 变量声明赋予初值,可…

matlab simulink永磁同步电机pid控制

1、内容简介 略 53-可以交流、咨询、答疑 2、内容说明 略 摘 要 19世纪90年代&#xff0c;美国西屋电气公司研制出了世界上第一台交流同步电机。随着科学技术的迅猛发展和生产工艺的持续进步&#xff0c;在20世纪50年代出现了永磁同步电机。它以永磁体代替电励磁绕组&#…

CSS重点

第一章&#xff1a;CSS类型 1、行内样式 <div style"color:red;font-size:30px;font-weight: 900;font-style: italic;">qcby</div>注意&#xff1a;行内样式&#xff0c;作用力优先级最高&#xff0c;但是不利于html与css的书写以及修改&#xff0c;会…

曲线生成 | 图解B样条曲线生成原理(附ROS C++/Python/Matlab仿真)

目录 0 专栏介绍1 控制点计算之插值2 控制点计算之近似3 仿真实现3.1 ROS C实现3.2 Python实现3.3 Matlab实现 0 专栏介绍 &#x1f525;附C/Python/Matlab全套代码&#x1f525;课程设计、毕业设计、创新竞赛必备&#xff01;详细介绍全局规划(图搜索、采样法、智能算法等)&a…

990-11产品经理:Team Building in Project Management 项目管理中的团队建设

Introduction One of the most important developments in management during the 1970’s has been the widespread application广泛应用 of project teams to a variety of complex tasks. Project managers quickly learn the critical significance批判意义 of the effect…

Android RecyclerView 如何展示自定义列表 Kotlin

Android RecyclerView 如何展示自定义列表 Kotlin 一、前提 有这么一个对象 class DeviceDemo (val name: String, val type: String, val address: String)要展示一个包含这个对象的列表 bluetoothDevices.add(DeviceDemo("bb 9800", "LE", "32:…

Qt QWiget 实现简约美观的加载动画 第三季

&#x1f603; 第三季来啦 &#x1f603; 这是最终效果: 只有三个文件,可以直接编译运行 //main.cpp #include "LoadingAnimWidget.h" #include <QApplication> #include <QVBoxLayout> #include <QGridLayout> int main(int argc, char *argv[]…

《Docker 简易速速上手小册》第8章 Docker 在企业中的应用(2024 最新版)

文章目录 8.1 Docker 在开发环境中的应用8.1.1 重点基础知识8.1.2 重点案例&#xff1a;Python Web 应用开发环境8.1.3 拓展案例 1&#xff1a;Python 数据分析环境8.1.4 拓展案例 2&#xff1a;Python 自动化测试环境 8.2 Docker 在生产环境的实践8.2.1 重点基础知识8.2.2 重点…

R语言在生态环境领域中的应用

R语言作为新兴的统计软件&#xff0c;以开源、自由、免费等特点风靡全球。生态环境领域研究内容广泛&#xff0c;数据常多样而复杂。利用R语言进行多元统计分析&#xff0c;从复杂的现象中发现规律、探索机制正是R的优势。为此&#xff0c;本课程以鱼类、昆虫、水文、地形等多样…

精品基于springboot健身房管理系统-教练会员卡管理

《[含文档PPT源码等]精品基于springboot健身房管理系统[包运行成功]》该项目含有源码、文档、PPT、配套开发软件、软件安装教程、项目发布教程、包运行成功&#xff01; 软件开发环境及开发工具&#xff1a; Java——涉及技术&#xff1a; 前端使用技术&#xff1a;HTML5,CS…

异常统一处理:Exception(兜底异常)

一、引言 本篇内容是“异常统一处理”系列文章的重要组成部分&#xff0c;主要聚焦于对 Exception&#xff08;兜底异常&#xff09; 的原理解析与异常处理机制&#xff0c;并给出测试案例。 关于 全局异常统一处理 的原理和完整实现逻辑&#xff0c;请参考文章&#xff1a; 《…

docker搭建zookeeper集群

文章目录 1. 集群搭建2. Leader选举3. Zookeeper集群角色 1. 集群搭建 这里我们使用docker-compose 搭建伪集群 version: 3.1 services:zoo1:image: zookeeperrestart: alwayscontainer_name: zoo1ports:- 2181:2181volumes:- /home/zk/zoo1/data:/data- /home/zk/zoo1/datal…

【数据结构初阶 7】二叉树:链式二叉树的基本操作实现

文章目录 &#x1f308; Ⅰ 定义二叉树结点&#x1f308; Ⅱ 创建二叉树结点&#x1f308; Ⅲ 遍历二叉树1. 先序遍历2. 中序遍历3. 后序遍历4. 层序遍历 &#x1f308; Ⅳ 销毁二叉树 &#x1f308; Ⅰ 定义二叉树结点 1. 每个结点都由三部分组成 数据域&#xff1a;存储本结…

【JVM】线上一次fullGC排查思路

fullGC问题背景 监控告警发现&#xff0c;今天开始我们线上应用频繁出现fullGC&#xff0c;并且每次出现后磁盘都会被占满 查看监控 查看监控发现FULLGC的机器均为同一个机房的集器&#xff0c;并且该机房有线上error报错&#xff0c;数据库监控对应的时间点也有异常&#x…

Vue3 路由配置 + 路由跳转 + 路由传参(动态路由传参 + 普通路由传参)

Vue Router&#xff1a; Vue.js 的官方路由。它与 Vue.js 核心深度集成&#xff0c;让用 Vue.js 构建单页应用变得轻而易举。 效果 一、介绍 1、官方文档&#xff1a;https://router.vuejs.org/zh/introduction.html 介绍 | Vue RouterVue.js 的官方路由https://router.vuejs.…

Java/Python/Go不同开发语言基础数据结构和相关操作总结-GC篇

Java/Python/Go不同开发语言基础数据结构和相关操作总结 1. 常见gc方式1.1 gc判断对象是否存活1.2 引用计数法1.2 标记-清除算法1.3 复制算法1.4 标记-压缩算法1.5 分代收集算法 2. java的gc方式以及垃圾回收器2.1 gc方式2.1 gc回收器2.1.1 Serial收集器2.1.2 ParNew收集器2.1.…

SSM---Mybatis查询数据库的功能

Mybatis查询数据库的功能流程&#xff1a; 在maven中加入mybatis依赖&#xff0c;mysql驱动依赖创建一张student表创建表对应的实体类&#xff1a;student类&#xff0c;用来保存表中的每行数据创建持久层的DAO接口&#xff0c;用来定义操作数据库的方法创建这个表对应的sql映…

计算机设计大赛 深度学习图像风格迁移 - opencv python

文章目录 0 前言1 VGG网络2 风格迁移3 内容损失4 风格损失5 主代码实现6 迁移模型实现7 效果展示8 最后 0 前言 &#x1f525; 优质竞赛项目系列&#xff0c;今天要分享的是 &#x1f6a9; 深度学习图像风格迁移 - opencv python 该项目较为新颖&#xff0c;适合作为竞赛课题…