新开一个文件,写入以下代码
const { app, BrowserWindow, ipcMain } = require('electron')
const { createProtocol} = require('vue-cli-plugin-electron-builder/lib')
const newWindow = {
id: '',
title: '',
width: '',
height: '',
minWidth: '',
minHeight: '',
route: '', // 页面路由URL '/manage?id=123'
darkTheme:true,
resizable: true, //是否支持调整窗口大小
maximize: false, //是否最大化
minimizable: true, //是否可以最小化
backgroundColor:'#eee', //窗口背景色
data: null, //数据
isMultiWindow: false, //是否支持多开窗口 (如果为false,当窗体存在,再次创建不会新建一个窗体 只focus显示即可,,如果为true,即使窗体存在,也可以新建一个)
isMainWin: false, //是否主窗口(当为true时会替代当前主窗口)
parentId: '', //父窗口id 创建父子窗口 -- 子窗口永远显示在父窗口顶部 【父窗口可以操作】
modal: false, //模态窗口 -- 模态窗口是禁用父窗口的子窗口,创建模态窗口必须设置 parent 和 modal 选项 【父窗口不能操作】
}
/**
* 窗口配置
*/
class Window {
constructor() {
this.parentWin = null
this.main = null //当前页
this.group = {} //窗口组
// this.tray = null; //托盘
}
// 窗口配置
configWindow(windowSize = []) {
return {
width: windowSize[0],
height: windowSize[1],
minWidth: null,
minHeight: null,
backgroundColor: '#ffff',
autoHideMenuBar: true, //自动隐藏菜单栏
titleBarStyle:'default',
resizable: true,
minimizable: true,
maximizable: true,
closable: true, //窗口是否可以关闭
frame: false, //创建一个无边框窗口
show: false,
webPreferences: {
contextIsolation: false, //上下文隔离
nodeIntegration: true, //启用Node集成(是否完整的支持 node)
webSecurity: false,
enableRemoteModule: true, //是否启用远程模块(即在渲染进程页面使用remote)
}
}
}
// 获取窗口
getWindow(id) {
return BrowserWindow.fromId(id)
}
// 获取全部窗口
getAllWindows() {
return BrowserWindow.getAllWindows()
}
// 创建窗口
createWindows(Invalidwin) {
console.log('------------开始创建窗口--------------')
let initialWindow = Object.assign({}, newWindow, Invalidwin)
// 判断窗口是否存在
for(let i in this.group) {
if(this.getWindow(Number(i))
&& this.group[i].route === initialWindow.route
&& !this.group[i].isMultiWindow) {
this.getWindow(Number(i)).focus()
return
}
}
let opt = this.configWindow([initialWindow.width || 960, initialWindow.height || 720])
if(initialWindow.parentId) {
opt.parent = this.getWindow(initialWindow.parentId)
console.log('parent id', opt.parent.width)
} else if(this.main) {
//console.log('是当前页')
}
if(typeof initialWindow.modal === 'boolean') {
opt.modal = initialWindow.modal
}
if(typeof initialWindow.resizable === 'boolean') {
opt.resizable = initialWindow.resizable
}
if(initialWindow.minWidth) {
opt.minWidth = initialWindow.minWidth
}
if(initialWindow.minHeight) {
opt.minHeight = initialWindow.minHeight
}
// console.log('opt', opt)
const win = new BrowserWindow(opt)
console.log('创建的窗口id:' + win.id)
this.group[win.id] = {
route: initialWindow.route,
mainWin: initialWindow.isMainWin,
}
// 是否最大化
if(initialWindow.maximize && initialWindow.resizable) {
win.maximize()
}
// 是否是当前窗口
if(initialWindow.isMainWin) {
if(this.main) {
delete this.group[this.main.id]
this.main.close()
}
this.main = win
}
initialWindow.id = win.id
win.on('close', () => win.setOpacity(0))
// win.loadFile('index.html')
// 打开网址(加载页面)
/**
* 开发环境: http://localhost:8080
* 正式环境: app://./index.html
*/
let winURL = ''
if (process.env.WEBPACK_DEV_SERVER_URL) {
//打开控制台
let devtools = null
devtools = new BrowserWindow()
win.webContents.setDevToolsWebContents(devtools.webContents)
win.webContents.openDevTools()
// Load the url of the dev server if in development mode
winURL = initialWindow.route ? `http://localhost:1919${initialWindow.route}` : 'http://localhost:1919'
}else {
createProtocol('app')
winURL = initialWindow.route ? `app://./index.html#${initialWindow.route}` : 'app://./index.html'
}
win.loadURL(winURL)
win.once('ready-to-show', () => {
win.show()
})
// 钩住窗口消息(-webkit-app-region: drag)
win.hookWindowMessage(278, function(e) {
win.setEnabled(false)
setTimeout(() => {
win.setEnabled(true)
}, 150)
return true
})
}
// 关闭所有窗口
closeAllWindow() {
for(let i in this.group) {
if(this.getWindow(Number(i))) {
// console.log('所有关闭', i)
this.getWindow(Number(i)).close()
} else {
app.quit()
}
}
// console.log('finally', this.group)
}
// 开启监听
listen() {
// 关闭
ipcMain.on('window-closed', (event, winId) => {
if(winId) {
// console.log('单个关闭1')
if(this.group[Number(winId)]) {
this.getWindow(Number(winId)).close()
delete this.group[Number(winId)]
}
}
console.log('删除后的', this.group)
})
//关闭所有
ipcMain.on('all-win-closed', (event, winId) => {
if (winId) {
// console.log('关闭所有的监听')
this.closeAllWindow()
}
})
// 隐藏
ipcMain.on('window-hide', (event, winId) => {
if (Object.keys(this.group).length === 1) {
this.closeAllWindow()
} else {
if(winId) {
this.getWindow(Number(winId)).hide()
}else {
for(let i in this.group) {
if (this.group[i]) {
this.getWindow(Number(i)).hide()
}
}
}
}
})
// 显示
ipcMain.on('window-show', (event, winId) => {
if(winId) {
this.getWindow(Number(winId)).show()
} else {
for(let i in this.group) {
if (this.group[i]) {
this.getWindow(Number(i)).show()
}
}
}
})
// 最小化
ipcMain.on('window-mini', (event, winId) => {
// console.log('resiable', this.getWindow(Number(winId)).resizable)
if(winId) {
this.getWindow(Number(winId)).minimize()
} else {
for(let i in this.group) {
if(this.group[i]) {
this.getWindow(Number(i)).minimize()
}
}
}
})
// 最大化
ipcMain.on('window-max', (event, winId) => {
if(winId) {
this.getWindow(Number(winId)).maximize()
} else {
for(let i in this.group) {
if(this.group[i]) {
this.getWindow(Number(i)).maximize()
}
}
}
})
// 最大化/还原
ipcMain.on('window-max-restore', (event, winId) => {
// console.log('最大化', this.getWindow(Number(winId)))
if(winId) {
if(this.getWindow(Number(winId)).isMaximized()) {
this.getWindow(Number(winId)).restore()
}else {
this.getWindow(Number(winId)).maximize()
}
}
})
// 重新加载
ipcMain.on('window-reload', (event, winId) => {
if(winId) {
this.getWindow(Number(winId)).reload()
} else {
for(let i in this.group) {
if(this.group[i]) {
this.getWindow(Number(i)).reload()
}
}
}
})
// 创建窗口
ipcMain.on('window-new', (event, initialWindow) => {
this.createWindows(initialWindow)
})
}
}
module.exports = {Window}
如果想在electron的主进程中,也就是background.js中引用:
require('@electron/remote/main').initialize()
const window = new Window()
/**创建首页 */
async function createWindow() {
window.listen()
window.createWindows({ route: '/welCome', width: 350, height: 254, isMainWin: false, modal: false })
//此处就是引用了上面文件的创建函数,可自定义各种参数。
//route一定要与你在router文件中所创建的页面路由一致。
}
如果需要在.vue文件中对窗口进行操作,则需要重新创建一个文件,去做electron和vue之间的‘中间人’。主进程中会监听每个函数的调用,从而对窗口进行操作,而渲染进程只需要调用以下函数即可,例如,我在index.vue文件中想调用关闭窗口,如下
//关闭窗口
const closed = () => {
// console.log(currentWindow.closable, currentWindow.id)
if (winRoute.value === '/mainBoardmonitoring') {
winClose.value.warningVisibled = true
}else if (winRoute.value === '/deviceHome') {
windowHide(2)//传入你所想要关闭的窗口id
} else{
if (currentWindow.closable) {
return windowClose(currentWindow.id)
}
winClose.value.warningVisibled = true
mainWindow.value = false
}
}
这是窗口的中间人文件pluginUtil.js
import { ipcRenderer, app } from'electron'
export function windowCreate(args) {
ipcRenderer.send('window-new', args)
}
/**
* 关闭窗口
*/
export function windowClose(id) {
ipcRenderer.send('window-closed', id)
}
// 显示窗口
export function windowShow(id) {
ipcRenderer.send('window-show', id)
}
//隐藏窗口
export function windowHide(id) {
ipcRenderer.send('window-hide', id)
}
//关闭所有窗口
export async function windowCloseAll() {
ipcRenderer.send('all-win-closed', -1)
}