赞
踩
electron是一个跨端开发桌面应用的框架,所以编译起来比较耗时,打开窗口也比较慢,为了避免每次都那么慢,或者每次打开都新建窗口,找到一个类似进程池的窗口池方法优化。
不多bb直接上封装代码:
const { BrowserWindow, ipcMain, } = require('electron') // 窗口池数组 var winItems = [] // 主要进程窗口 var mainWin // 是否初始化完成 var isInit // 子窗口配置数据 var winConfigJson = { // 设置 setting: { name: "setting", size: { width: 550, height: 470, }, }, // 意见反馈 feedback: { name: "feedback", size: { width: 360, height: 224, }, }, // 备份与恢复 backup: { name: "backup", size: { width: 551, height: 371, }, }, // 图片详情弹窗 imageDialog: { name: "imageDialog", size: { width: 595, height: 543, }, open: (e) => { let minW = 470; let maxW = 966; let minH = 487; let maxH = 676; let width = e.width + 2 let height = e.height + 42 const setWH = (self, min, max) => { if (self < min) { return min } else if (self > min && self < max) { return self } else { return max } } winConfigJson.imageDialog.size.width = setWH(width, minW, maxW) winConfigJson.imageDialog.size.height = setWH(height, minH, maxH) } }, // 截图 screen: { name: "screen", fullscreen: true, resizable: false, nodeIntegration: false, close: (flag) => { flag && mainWin.webContents.send("isScreen") } } } // webpreferences配置 class ConfigWebPreferences { // nodeIntegration = true // devTools = false webSecurity = false } // 窗口配置 class ConfigWindow { maximizable = true resizable = true center = true frame = false show = false webPreferences = new ConfigWebPreferences() model = true parent = mainWin fullscreenable = true transparent = true } // 新建窗口 class WindowPoolItem { constructor() { let config = new ConfigWindow() this.win = new BrowserWindow(config) this.param = null this.initEvent() this.loadUrl(this.win, "/blank") } // 根据环境变量拼接页面绝对地址并让窗口加载 getTotalUrl(url) { if (process.env.NODE_ENV !== "production") { return `http://localhost:9080/#${url}` } else { return `file://${__dirname}/index.html#/${url}` } } // 加载窗口 async loadUrl(win, url) { let totalUrl = this.getTotalUrl(url) await win.loadURL(totalUrl) } // 初始化窗口事件 initEvent() { this.win.on("close", () => { for (let i = 0; i < winItems.length; i++) { if (winItems[i].param && winItems[i].param.name == this.param.name) { winItems.splice(i, 1) } } }) } // 使用一个窗口 use(windowParam) { this.effectParam(windowParam) this.loadUrl(this.win, windowParam.name) } // 展示窗口 effectParam(param) { this.param = param // this.win.setAlwaysOnTop(true) this.controlSize() // this.win.moveTop() this.win.center(); !isInit && (this.win.show()) } // 设置窗口大小等相关配置 controlSize() { if (this.param.size) { this.win.setSize(this.param.size.width, this.param.size.height) } if (this.param.resizable === false) { this.win.setResizable(false) if (this.param.fullscreen) { this.win.setFullScreen(true) // console.log("是否全屏", this.win.isFullScreen()); } return } else if (this.param.minSize) { this.win.setMinimumSize(this.param.minSize.width, this.param.minSize.height) this.win.setResizable(true) return } this.win.setResizable(true) this.win.setMinimumSize(200, 150) } } class InitWindowPool { constructor(mainWindow) { // 初始化窗口池 this.winItems = winItems isInit = true mainWin = mainWindow this.init() } init() { // 初始化三个 for (let i = 0; i < 3; i++) { winItems.push(new WindowPoolItem()) } for (let i in winConfigJson) { let name = i // 特定页面可以先预加载 if (name == 'screen' || name == 'imageDialog') { this.picAndUse(winConfigJson[name]) } // 窗口打开 ipcMain.on(name + '-open', (e, data) => { // 如果菜单中包含open函数则运行 'open' in winConfigJson[i] && winConfigJson[i].open(data) let param = winConfigJson[name] if (!this.isWindowInUse(param)) this.picAndUse(param) this.curWin(name).webContents.send(name + 'Show', data) }) // 缩小 ipcMain.on(name + '-min', e => { this.curWin(name).minimize() }) // 放大 ipcMain.on(name + '-max', e => { if (this.curWin(name).isMaximized()) { this.curWin(name).restore() } else { this.curWin(name).maximize() } }) // 关闭 ipcMain.on(name + '-close', (e, data) => { 'close' in winConfigJson[i] && winConfigJson[i].close(data) this.curWin(name).hide() }) } isInit = false } // 已有窗口则直接展示 isWindowInUse(param) { let item = winItems.find((v) => v.param && v.param.name === param.name) if (!item) return false item.effectParam(param) return true } // 当前窗口 curWin(name) { return winItems.find((v) => v.param && v.param.name === name).win } // 使用一个窗口并创建一个新的 picAndUse(param) { let item = winItems.find((v) => !v.param) //没有param属性的,就是没用过的 // 使用 item.use(param) winItems.push(new WindowPoolItem()) } } export default InitWindowPool
导入主进程实例化即可,上面winConfigJson 子窗口菜单可自行配置,不明白的可评论区留言
import { app, BrowserWindow, Menu, Tray, ipcMain, } from 'electron' import path from 'path' import '../renderer/store' import InitWindowPool from "../renderer/utils/winPool"; /** * Set `__static` path to static files in production * https://simulatedgreg.gitbooks.io/electron-vue/content/en/using-static-assets.html */ if (process.env.NODE_ENV !== 'development') { global.__static = require('path').join(__dirname, '/static').replace(/\\/g, '\\\\') } let mainWindow, tray = null, trayIcon1 = null, trayIcon2 = null const winURL = process.env.NODE_ENV === 'development' ? `http://localhost:9080` : `file://${__dirname}/index.html` function createWindow() { /** * Initial window options */ mainWindow = new BrowserWindow({ height: 530, useContentSize: true, width: 350, frame: false, transparent: true, icon: `${__static}/tray.ico`, webPreferences: { nodeIntegration: true, // devTools: false, webSecurity: false, // 跨域 } }) // 初始化窗口池 var windowPool = new InitWindowPool(mainWindow) console.log("窗口池", windowPool); mainWindow.loadURL(winURL); mainWindow.on('closed', () => { mainWindow = null app.quit() }) createTray() } ipcMain.on("closeQuit", () => { app.quit() }) app.on('ready', createWindow)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。