招聘網(wǎng)站上怎么做推廣青島網(wǎng)站建設公司電話
文章目錄
- 引入
- 思路
- 抽出公共聲明文件
- 抽出全局通用數(shù)據(jù)類型和方法
- 主進程模塊
- 1.抽離基礎常量
- 2.封裝窗口工具類
- 渲染進程模塊
- 測試結果
引入
demo項目地址
可以看到我們之前在主進程中的邏輯全部都塞到index.ts文件中,包括窗口的一些事件處理,handle監(jiān)聽,協(xié)議注冊等等,后期維護起來會比較麻煩,我們不妨將其中的功能細分,封裝到工具類中。
思路
以新建窗口舉例,流程為
- 主進程ipcMain.handle監(jiān)聽,根據(jù)傳來的參數(shù)構建新窗口
/*** 新建一個窗口* route=>路由地址 paramJsonStr => 序列化后的參數(shù)對象*/
ipcMain.handle("open-win", (_, route: string, paramJsonStr: string) => {...})
- 渲染進程調用 ipcRenderer.invoke方法通知主進程創(chuàng)建窗口
/*** 新建一個窗口* @param path 路由地址* @param param 傳遞的參數(shù)*/
export function openWindow(path: string, param?: Object) {...ipcRenderer.invoke("open-win", path, paramJsonStr);
}
可以預見的是,后續(xù)窗口的創(chuàng)建邏輯會隨著業(yè)務邏輯而擴展,例如創(chuàng)建窗口時 指定窗口寬高,標題,背景色等屬性,設置窗口透明,事件擊穿等等內容,并且多個窗口間的一些交互需要我們去維護一個窗口組信息,記錄窗口的id和邏輯上的關聯(lián)關系等。
所以我們不妨創(chuàng)建一個窗口工具類,專門集成封裝窗口相關的方法,屬性等
抽出公共聲明文件
我們在渲染進程項目模塊中的electronUtils和主進程中的窗口工具類中的【handle/on】方法是一一對應的【invoke/send】,傳入的參數(shù)也是通用的,所以我們不妨抽出一個公共的全局聲明文件,用于聲明通用的一些參數(shù)對象。
1.在全局聲明文件中添加通用事件對象的聲明
- types\global.d.ts
/** 一些全局的對象補充聲明 */
export {};
declare global {...// 窗口創(chuàng)建參數(shù)規(guī)范interface IWindowConfig {key?: string; // 窗口唯一key,不傳則取窗口的id,假如已存在該key則聚焦該窗口route?: string; // 窗口路由width?: number; // 窗口寬度height?: number; // 窗口高度param?: string; // 傳遞參數(shù),新窗口打開時能直接從路由中獲取,拼接url傳遞,推薦只傳小數(shù)據(jù)}
}
2.主進程引入全局聲明文件
- electron\electron-env.d.ts
/// <reference types="vite-plugin-electron/electron-env" />import "../types/global.d.ts";
抽出全局通用數(shù)據(jù)類型和方法
主進程和渲染進程都會調用相同的事件名稱,所以我們不妨定義一個全局的事件枚舉類,方便兩個進程的代碼書寫和規(guī)范【事件名稱應當唯一,否則會重復綁定】。
1.在根目錄下創(chuàng)建globel目錄,然后分別創(chuàng)建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環(huán)境請求地址
export const url = process.env.VITE_DEV_SERVER_URL;
// 部署環(huán)境的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上注冊表的協(xié)議
export const PROTOCOL = 'bcxlelectrondemo';
2.封裝窗口工具類
注意:
1.定義默認窗口參數(shù)時使用了ts中的聯(lián)合類型,這樣定義的defaultWindowConfig就必須擁有指定的兩個類型中的所有屬性
2.創(chuàng)建了一個窗口類,并將窗口相關的邏輯封裝為窗口類中的成員方法
3.窗口類中定義個一個listen方法,里面放置所有需要與渲染進程交互的handle監(jiān)聽
- electron\main\windowUtils.ts
import {BrowserWindow,BrowserWindowConstructorOptions,ipcMain,
} from "electron";
import {url,appTitle,preloadPath,iconPath,indexHtmlPath,
} from "./common/variables";
import { CustomChannel } from "../../globel/channelEvent";/* ======================= 定義一些窗口工具類中會使用到的常量,以及窗口頂級父類 ========================= */// 默認窗口參數(shù)
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 {// 事件監(jiān)聽處理listen() {// 窗口創(chuàng)建監(jiān)聽ipcMain.handle(CustomChannel.window_create, (_, opt: IWindowConfig) => {this.createWindows(opt);});}/*** 創(chuàng)建窗口* @param windowConfig 窗口創(chuàng)建參數(shù)*/createWindows(windowConfig: IWindowConfig): BrowserWindow {// 創(chuàng)建窗口對象const win = new BrowserWindow(Object.assign({}, defaultWindowConfig, windowConfig));// 根據(jù)當前環(huán)境加載頁面,并傳遞參數(shù)const param = windowConfig.param? "?urlParamData=" + windowConfig.param: "";if (process.env.VITE_DEV_SERVER_URL) {// 如果是開發(fā)環(huán)境,則直接訪問本地跑起的服務,拼接對應的路由win.loadURL(`${url}#${windowConfig.route}${param}`);} else {// 如果是線上環(huán)境,則加載html文件的路徑,然后拼接路由win.loadFile(indexHtmlPath, { hash: windowConfig.route + param });}// 綁定通用窗口事件return win;}
}
接著我們調整index.ts中的創(chuàng)建主窗口的代碼:
import {WindowUtils} from './windowUtils'// 創(chuàng)建窗口工具類
const windowUtils = new WindowUtils();
windowUtils.listen();...
async function createWindow() {...win = windowUtils.createWindows({route:"/"});
}
對比之前代碼,簡練了不少
渲染進程模塊
1.我們調整通用交互工具類,補充新的窗口創(chuàng)建方法
- 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: "向你問個好~~",}),});
測試結果
能夠正常的創(chuàng)建窗口