Electron 项目目录结构解析
源代码仓库:
Github仓库【electron_git】

一、main/index.js 主进程代码解读
js
import { app, shell, BrowserWindow, ipcMain } from 'electron'
import { join } from 'path'
import { electronApp, optimizer, is } from '@electron-toolkit/utils'
import icon from '../../resources/icon.png?asset'
/**
* @description 创建主窗口
* 1、通过 new BrowserWindow 创建窗口,并设置了窗口的一系列属性,比如宽度、高度、是否显示、是否隐藏菜单栏等
* 2、通过 on('ready-to-show', () => { mainWindow.show() }) 在窗口准备好显示时显示窗口
* 3、通过 webContents.setWindowOpenHandler((details) => { shell.openExternal(details.url) }) 设置窗口打开链接的行为
* 4、通过 loadURL(process.env['ELECTRON_RENDERER_URL']) 加载渲染进程的 URL,如果是在开发环境下,则加载 process.env['ELECTRON_RENDERER_URL'],否则加载本地的 index.html 文件
*/
function createWindow() {
// Create the browser window.
const mainWindow = new BrowserWindow({
width: 900,
height: 670,
show: false,
autoHideMenuBar: true,
...(process.platform === 'linux' ? { icon } : {}),
webPreferences: {
preload: join(__dirname, '../preload/index.js'),
sandbox: false
}
})
mainWindow.on('ready-to-show', () => {
mainWindow.show()
})
mainWindow.webContents.setWindowOpenHandler((details) => {
shell.openExternal(details.url)
return { action: 'deny' }
})
// HMR for renderer base on electron-vite cli.
// Load the remote URL for development or the local html file for production.
if (is.dev && process.env['ELECTRON_RENDERER_URL']) {
mainWindow.loadURL(process.env['ELECTRON_RENDERER_URL'])
} else {
mainWindow.loadFile(join(__dirname, '../renderer/index.html'))
}
}
/**
* @description 当 Electron 完成初始化并且准备好创建浏览器窗口时,这个方法会被调用
* 1、通过 electronApp.setAppUserModelId('com.electron') 设置应用的用户模型 ID
* 2、通过 app.on('browser-window-created', (_, window) => { optimizer.watchWindowShortcuts(window) }) 监听浏览器窗口创建事件,并使用 optimizer.watchWindowShortcuts(window) 监听窗口快捷键
* 3、通过 ipcMain.on('ping', () => console.log('pong')) 监听渲染进程发送的 ping 事件,并返回 pong
* 4、通过 createWindow() 创建主窗口
* 5、通过 app.on('activate', function () { if (BrowserWindow.getAllWindows().length === 0) createWindow() }) 监听激活事件,如果没有任何窗口打开,则创建一个新窗口
*/
app.whenReady().then(() => {
// Set app user model id for windows
electronApp.setAppUserModelId('com.electron')
// Default open or close DevTools by F12 in development
// and ignore CommandOrControl + R in production.
// see https://github.com/alex8088/electron-toolkit/tree/master/packages/utils
app.on('browser-window-created', (_, window) => {
optimizer.watchWindowShortcuts(window)
})
// 监听渲染进程发送的 ping 事件,并返回 pong
ipcMain.on('ping', () => console.log('pong'))
createWindow()
app.on('activate', function () {
// On macOS it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (BrowserWindow.getAllWindows().length === 0) createWindow()
})
})
/**
* @description 当所有窗口关闭时,如果是在 macOS 上,则不退出应用程序,否则退出应用程序
*/
app.on('window-all-closed', () => {
if (process.platform !== 'darwin') {
app.quit()
}
})
// In this file you can include the rest of your app's specific main process
// code. You can also put them in separate files and require them here.
Electron 常用回调事件
主进程 (Main Process) 事件
app
事件
事件名 | 触发时机 | 说明 |
---|---|---|
app.whenReady() |
Electron 初始化完成后 | 应用准备就绪,可创建窗口 |
app.on('window-all-closed', callback) |
所有窗口关闭时 | 在 macOS 需要手动退出应用 |
app.on('before-quit', callback) |
应用退出前 | 适合做清理工作 |
app.on('will-quit', callback) |
应用即将退出 | 取消 quit 事件可以阻止退出 |
app.on('activate', callback) |
macOS 上点击 Dock 图标时 | 适用于 macOS 上重新创建窗口 |
app.on('ready', callback) |
Electron 初始化完成后 | 监听 ready 事件创建窗口 |
BrowserWindow
事件
事件名 | 触发时机 | 说明 |
---|---|---|
browserWindow.on('close', callback) |
窗口即将关闭 | 可以阻止窗口关闭 |
browserWindow.on('closed', callback) |
窗口关闭后 | 窗口对象被销毁 |
browserWindow.on('focus', callback) |
窗口获取焦点时 | 可用于 UI 交互逻辑 |
browserWindow.on('blur', callback) |
窗口失去焦点时 | 可用于暂停某些操作 |
browserWindow.on('maximize', callback) |
窗口最大化时 | 适用于 UI 适配 |
browserWindow.on('unmaximize', callback) |
取消最大化时 | 适用于 UI 适配 |
browserWindow.on('minimize', callback) |
窗口最小化时 | 适用于后台任务管理 |
browserWindow.on('restore', callback) |
窗口恢复时 | 用于 UI 适配 |
browserWindow.on('resize', callback) |
窗口大小变化时 | 适用于自适应 UI |
渲染进程 (Renderer Process) 事件
ipcRenderer
事件
事件名 | 触发时机 | 说明 |
---|---|---|
ipcRenderer.send(channel, ...args) |
发送事件到主进程 | 渲染进程向主进程发送数据 |
ipcRenderer.on(channel, callback) |
监听主进程事件 | 主进程返回数据时触发 |
ipcRenderer.once(channel, callback) |
监听事件(仅触发一次) | 监听一次后自动移除 |
ipcRenderer.removeListener(channel, callback) |
移除指定监听事件 | 清理监听,防止内存泄漏 |
ipcRenderer.removeAllListeners(channel) |
移除所有监听事件 | 彻底清除事件 |
系统级事件
powerMonitor
事件
事件名 | 触发时机 | 说明 |
---|---|---|
powerMonitor.on('suspend', callback) |
系统进入睡眠 | 监听系统进入睡眠 |
powerMonitor.on('resume', callback) |
系统恢复运行 | 监听系统从睡眠恢复 |
powerMonitor.on('on-ac', callback) |
连接电源适配器 | 监听设备充电 |
powerMonitor.on('on-battery', callback) |
使用电池供电 | 监听设备断开电源 |
systemPreferences
事件
事件名 | 触发时机 | 说明 |
---|---|---|
systemPreferences.getAccentColor() |
获取系统主题颜色 | 适用于 UI 适配 |
systemPreferences.getEffectiveAppearance() |
获取深色/浅色模式 | 适用于 UI 主题切换 |
快捷键事件
globalShortcut
事件
事件名 | 触发时机 | 说明 |
---|---|---|
globalShortcut.register('CommandOrControl+X', callback) |
监听快捷键 | 可用于全局快捷键 |
globalShortcut.unregisterAll() |
移除所有快捷键 | 适用于应用关闭时清理 |