从小白到精通——Electron桌面应用开发全攻略
一、认识 Electron
Electron 是一个使用 HTML、CSS 和 JavaScript 开发跨平台桌面应用的框架。它结合了 Chromium(用于界面渲染) 与 Node.js(用于系统能力),让前端开发者能够轻松构建 Windows、macOS 和 Linux 应用程序。
一些知名的 Electron 应用包括 VS Code、Slack、GitHub Desktop 和 Postman。
学习 Electron 需要掌握以下关键概念:
- 主进程与渲染进程
- IPC 通信机制
- 窗口与菜单管理
- 文件操作与系统交互
- 打包与发布
二、环境准备
首先,安装 Node.js。然后创建项目目录并初始化:
mkdir my-electron-app
cd my-electron-app
npm init -y
接着安装 Electron:
npm install electron --save-dev
在 package.json 文件中添加启动脚本:
"scripts": {
"start": "electron ."
}
三、第一个 Electron 应用
创建主进程入口文件 main.js:
const { app, BrowserWindow } = require('electron');
function createWindow() {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
});
win.loadFile('index.html');
}
app.whenReady().then(createWindow);
创建页面文件 index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Hello Electron</title>
</head>
<body>
<h1>欢迎来到 Electron 桌面应用</h1>
<button id="btn">点击我</button>
<script>
document.getElementById('btn').addEventListener('click', () => {
alert('Electron 真好玩!');
});
</script>
</body>
</html>
启动应用:
npm start
四、主进程与渲染进程
Electron 的架构类似于浏览器:主进程负责创建窗口和处理系统事件,而渲染进程负责页面渲染和 UI 逻辑。主进程可以创建多个窗口,每个窗口对应一个渲染进程。
const win1 = new BrowserWindow({ width: 500, height: 400 });
const win2 = new BrowserWindow({ width: 400, height: 300 });
五、窗口操作
创建窗口时可以设置各种属性,例如禁用缩放、指定图标等:
const win = new BrowserWindow({
width: 800,
height: 600,
resizable: false,
fullscreenable: false,
icon: 'icon.png'
});
win.loadFile('index.html');
win.webContents.openDevTools(); // 打开开发者工具
六、IPC 通信机制
主进程与渲染进程之间通过 IPC 进行数据通信。
在主进程 main.js 中:
const { ipcMain } = require('electron');
ipcMain.on('send-message', (event, msg) => {
console.log('收到消息:', msg);
event.reply('reply-message', '你好,渲染进程!');
});
在渲染进程 index.html 中:
const { ipcRenderer } = require('electron');
ipcRenderer.send('send-message', '来自渲染进程的问候');
ipcRenderer.on('reply-message', (event, msg) => {
alert(msg);
});
七、文件系统访问
Electron 集成了 Node.js,可以直接使用 fs 模块操作本地文件。
const fs = require('fs');
// 写入文件
fs.writeFileSync('data.txt', 'Electron 写入测试');
// 读取文件
const data = fs.readFileSync('data.txt', 'utf-8');
console.log('文件内容:', data);
八、创建菜单与快捷键
定义菜单模板并设置应用菜单:
const { Menu, app } = require('electron');
const template = [
{
label: '文件',
submenu: [
{ label: '新建', click: () => console.log('新建文件') },
{ type: 'separator' },
{ label: '退出', role: 'quit' }
]
},
{
label: '帮助',
submenu: [{ label: '关于', click: () => console.log('关于我们') }]
}
];
const menu = Menu.buildFromTemplate(template);
Menu.setApplicationMenu(menu);
九、右键菜单
实现自定义右键菜单,首先在主进程中监听事件:
const { Menu, MenuItem } = require('electron');
const { ipcMain } = require('electron');
ipcMain.on('show-context-menu', (event) => {
const template = [
{ label: '复制', role: 'copy' },
{ label: '粘贴', role: 'paste' }
];
const menu = Menu.buildFromTemplate(template);
menu.popup();
});
在渲染进程中触发右键菜单:
document.addEventListener('contextmenu', (e) => {
e.preventDefault();
ipcRenderer.send('show-context-menu');
});
十、打开系统对话框
使用 dialog 模块打开文件选择对话框:
const { dialog } = require('electron');
async function openFileDialog() {
const result = await dialog.showOpenDialog({
properties: ['openFile', 'multiSelections']
});
console.log(result.filePaths);
}
十一、系统通知
发送桌面通知:
new Notification('提示', {
body: '任务执行完毕!'
});
十二、托盘图标
创建系统托盘图标和上下文菜单:
const { Tray, Menu } = require('electron');
let tray = null;
app.whenReady().then(() => {
tray = new Tray('icon.png');
const contextMenu = Menu.buildFromTemplate([
{ label: '显示窗口', click: () => win.show() },
{ label: '退出', click: () => app.quit() }
]);
tray.setToolTip('我的Electron应用');
tray.setContextMenu(contextMenu);
});
十三、自动更新
集成自动更新功能,使用 electron-updater:
const { autoUpdater } = require('electron-updater');
autoUpdater.checkForUpdatesAndNotify();
autoUpdater.on('update-downloaded', () => {
autoUpdater.quitAndInstall();
});
十四、SQLite 本地数据库
安装 SQLite 并操作本地数据库:
npm install sqlite3
在代码中使用:
const sqlite3 = require('sqlite3').verbose();
const db = new sqlite3.Database('data.db');
db.serialize(() => {
db.run("CREATE TABLE IF NOT EXISTS user (id INTEGER PRIMARY KEY, name TEXT)");
db.run("INSERT INTO user (name) VALUES (?)", ['张三']);
db.each("SELECT * FROM user", (err, row) => console.log(row));
});
十五、集成前端框架
可以将 React 或 Vue 等前端框架打包后嵌入 Electron。例如,加载开发服务器或构建后的文件:
win.loadURL('http://localhost:5173'); // 指向 Vite 开发服务器
// 或
win.loadFile('dist/index.html'); // 加载构建后的文件
十六、窗口间通信
多个窗口之间通过主进程中转进行通信:
ipcMain.on('broadcast', (event, msg) => {
win2.webContents.send('message', msg);
});
十七、保存用户配置
使用 electron-store 来管理用户配置:
npm install electron-store
在代码中使用:
const Store = require('electron-store');
const store = new Store();
store.set('theme', 'dark');
console.log(store.get('theme'));
十八、打包应用
安装打包工具并配置:
npm install electron-builder --save-dev
在 package.json 中添加构建配置:
"build": {
"appId": "com.example.myapp",
"productName": "MyElectronApp",
"win": {
"target": "nsis"
}
}
运行打包命令:
npx electron-builder
这将生成可执行文件(如 .exe、.dmg 或 .AppImage)。
十九、自动启动应用
使用 electron-auto-launch 实现应用开机自启:
npm install electron-auto-launch
在代码中启用:
const AutoLaunch = require('electron-auto-launch');
const appLauncher = new AutoLaunch({
name: 'MyElectronApp'
});
appLauncher.enable();
二十、完整实战项目:记事本桌面应用
创建一个简单的记事本应用,演示文件保存功能。
主进程 main.js:
const { app, BrowserWindow, ipcMain } = require('electron');
const fs = require('fs');
let win;
function createWindow() {
win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
nodeIntegration: true
}
});
win.loadFile('index.html');
}
ipcMain.on('save-text', (event, text) => {
fs.writeFileSync('note.txt', text);
event.reply('saved', '文件已保存到 note.txt');
});
app.whenReady().then(createWindow);
页面文件 index.html:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Electron 记事本</title>
</head>
<body>
<h2>简单记事本</h2>
<textarea id="content" rows="10" cols="60"></textarea><br>
<button id="saveBtn">保存</button>
<script>
const { ipcRenderer } = require('electron');
document.getElementById('saveBtn').addEventListener('click', () => {
const text = document.getElementById('content').value;
ipcRenderer.send('save-text', text);
});
ipcRenderer.on('saved', (e, msg) => alert(msg));
</script>
</body>
</html>
运行应用后,你将拥有一个带文件保存功能的桌面记事本。