Electron 核心 API 全解析:从基础到实战场景

Electron 凭借丰富的 API 体系,让前端开发者能轻松调用系统级能力。本文将系统梳理 Electron 核心 API 的分类、使用场景及实战示例,帮你快速掌握从窗口管理到进程通信的全场景开发。

一、主进程核心 API(Main Process)

主进程是 Electron 应用的入口,负责管理应用生命周期、窗口创建及系统交互,运行在 Node.js 环境中。

1. app:应用生命周期的"总控中心"

核心功能:控制应用启动、退出、路径管理等全局行为,是应用的"生命周期管家"。

常用方法与场景
方法/事件 作用 典型场景
app.whenReady() 等待应用初始化完成后执行回调 应用启动后创建主窗口
app.getPath(name) 获取系统目录路径(如用户数据目录) 存储应用配置、日志文件
app.quit() 强制退出应用 响应"退出"菜单点击
app.on('window-all-closed') 监听所有窗口关闭事件 非 macOS 系统自动退出应用
app.on('activate') macOS 下点击 Dock 图标时触发 重新创建窗口(窗口全部关闭后)
实战示例:基础生命周期管理
javascript 复制代码
const { app, BrowserWindow } = require('electron')
const path = require('path')

// 保存主窗口实例(避免被垃圾回收)
let mainWindow = null

// 应用初始化完成后创建窗口
app.whenReady().then(() => {
  createMainWindow()
  
  // macOS 特有:Dock 图标点击时重建窗口
  app.on('activate', () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createMainWindow()
    }
  })
})

// 所有窗口关闭时退出(Windows/Linux)
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') { // 排除 macOS
    app.quit()
  }
})

// 创建主窗口的工具函数
function createMainWindow() {
  mainWindow = new BrowserWindow({
    width: 800,
    height: 600,
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })
  mainWindow.loadFile('index.html')
}

// 获取系统路径示例(如用户数据目录)
const userDataPath = app.getPath('userData') 
console.log('应用数据目录:', userDataPath) // 输出:C:\Users\用户名\AppData\Roaming\应用名(Windows)

2. BrowserWindow:窗口管理的"基石"

核心功能:创建和控制应用窗口,支持自定义尺寸、样式及行为,是用户交互的载体。

核心配置与场景
配置项 作用 典型场景
width/height 窗口初始宽高 基础窗口尺寸设置
minWidth/minHeight 窗口最小宽高 限制窗口缩放范围
frame: false 禁用窗口边框(无边框窗口) 自定义标题栏、沉浸式 UI
fullscreen: true 全屏显示 视频播放器、演示类应用
webPreferences 网页渲染配置(核心安全配置) 控制 Node 集成、预加载脚本
show: false 初始隐藏窗口 窗口加载完成后再显示(避免白屏)
实战示例 1:无边框窗口(带自定义标题栏)
javascript 复制代码
// 创建无边框窗口
const borderlessWindow = new BrowserWindow({
  width: 900,
  height: 600,
  frame: false, // 禁用系统边框
  webPreferences: {
    preload: path.join(__dirname, 'preload.js')
  }
})

// 加载页面
borderlessWindow.loadFile('borderless.html')

// 无边框窗口的 HTML 中需配置可拖拽区域(CSS)
/* 
.title-bar {
  -webkit-app-region: drag; /* 允许拖拽 */
  height: 32px;
  background: #333;
  color: white;
}
.title-bar-button {
  -webkit-app-region: no-drag; /* 按钮禁止拖拽 */
  margin: 4px;
  padding: 4px 8px;
}
*/
实战示例 2:窗口加载优化(避免白屏)
javascript 复制代码
const splashWindow = new BrowserWindow({
  width: 400,
  height: 300,
  frame: false,
  transparent: true, // 透明背景
  alwaysOnTop: true // 始终置顶
})
splashWindow.loadFile('splash.html') // 加载启动屏

// 主窗口配置
const mainWindow = new BrowserWindow({
  width: 1000,
  height: 700,
  show: false, // 初始隐藏
  webPreferences: { preload: path.join(__dirname, 'preload.js') }
})

// 主窗口加载完成后显示并关闭启动屏
mainWindow.loadFile('index.html').then(() => {
  mainWindow.show() // 显示主窗口
  splashWindow.destroy() // 销毁启动屏
})

3. ipcMain:主进程通信的"接收器"

核心功能:处理渲染进程发送的消息,支持同步/异步通信,是主进程与渲染进程交互的"桥梁"。

通信模式与场景
模式 方法 适用场景
异步通信 ipcMain.handle(channel, handler) 耗时操作(文件读写、网络请求)
同步通信 ipcMain.on(channel, (event, data) => { ... }) 简单数据获取(无阻塞风险)
主进程主动推送 webContents.send(channel, data) 实时数据更新(如定时任务、系统事件)
实战示例 1:异步文件读取(安全的进程通信)
javascript 复制代码
// 主进程(main.js)
const { ipcMain, fs } = require('electron')
const path = require('path')

// 注册异步通信通道:读取文件内容
ipcMain.handle('file:read', async (event, filePath) => {
  try {
    // 安全校验:限制只能读取应用数据目录下的文件
    const userDataPath = app.getPath('userData')
    if (!filePath.startsWith(userDataPath)) {
      throw new Error('无权访问该文件(仅允许读取应用数据目录)')
    }
    // 读取文件
    const content = fs.readFileSync(filePath, 'utf8')
    return { success: true, content }
  } catch (err) {
    return { success: false, error: err.message }
  }
})

// 渲染进程通过预加载脚本调用(preload.js)
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
  readFile: (filePath) => ipcRenderer.invoke('file:read', filePath)
})

// 渲染进程(renderer.js)
async function loadFile() {
  const result = await window.electronAPI.readFile('/path/to/file.txt')
  if (result.success) {
    console.log('文件内容:', result.content)
  } else {
    alert('读取失败:' + result.error)
  }
}
实战示例 2:主进程主动推送实时数据
javascript 复制代码
// 主进程:每秒推送当前时间
let mainWindow = new BrowserWindow(/* 配置 */)

setInterval(() => {
  const time = new Date().toLocaleTimeString()
  // 通过 webContents 向渲染进程推送消息
  mainWindow.webContents.send('time:update', time)
}, 1000)

// 预加载脚本暴露监听方法(preload.js)
contextBridge.exposeInMainWorld('electronAPI', {
  onTimeUpdate: (callback) => {
    ipcRenderer.on('time:update', (event, time) => callback(time))
  }
})

// 渲染进程:显示实时时间
window.electronAPI.onTimeUpdate((time) => {
  document.getElementById('clock').textContent = `当前时间:${time}`
})

4. dialog:系统对话框的"调用器"

核心功能:显示原生文件选择、消息提示、确认框等对话框,提供与系统一致的交互体验。

常用方法与场景
方法 作用 典型场景
showOpenDialog() 打开文件/目录选择对话框 导入文件、选择保存目录
showSaveDialog() 打开文件保存对话框 导出数据、保存编辑内容
showMessageBox() 显示消息提示框(支持警告、错误等类型) 操作确认、错误提示、信息通知
实战示例 1:多类型文件选择器
javascript 复制代码
const { dialog } = require('electron')

// 打开支持多种格式的文件选择器
async function openMultiTypeFile() {
  const { filePaths, canceled } = await dialog.showOpenDialog({
    title: '选择媒体文件',
    defaultPath: app.getPath('documents'), // 默认打开"文档"目录
    properties: ['openFile', 'multiSelections'], // 支持多选文件
    filters: [ // 限制文件类型
      { name: '图片', extensions: ['jpg', 'png', 'gif'] },
      { name: '视频', extensions: ['mp4', 'mov', 'avi'] },
      { name: '所有文件', extensions: ['*'] }
    ]
  })

  if (!canceled) {
    console.log('选中的文件:', filePaths) // 输出选中的文件路径数组
  }
}
实战示例 2:带自定义按钮的消息框
javascript 复制代码
const { dialog } = require('electron')

// 显示带自定义按钮的确认框
async function showCustomMessageBox() {
  const { response, checkboxChecked } = await dialog.showMessageBox({
    type: 'question', // 对话框类型(info/warning/error/question)
    title: '操作确认',
    message: '是否删除该文件?',
    detail: '删除后将无法恢复,是否继续?',
    buttons: ['取消', '删除', '移到回收站'], // 自定义按钮
    defaultId: 0, // 默认选中第1个按钮(索引从0开始)
    checkboxLabel: '不再提示', // 复选框文本
    checkboxChecked: false // 复选框初始状态
  })

  // 处理用户选择
  switch (response) {
    case 0: // 取消
      console.log('用户取消操作')
      break
    case 1: // 删除
      console.log('用户选择直接删除')
      break
    case 2: // 移到回收站
      console.log('用户选择移到回收站')
      break
  }
  
  if (checkboxChecked) {
    console.log('用户勾选了"不再提示"')
  }
}

核心功能:创建应用菜单(顶部菜单栏/上下文菜单)和系统托盘图标,支持自定义交互逻辑。

应用场景
  • Menu:创建顶部菜单栏(如文件、编辑、帮助)、右键上下文菜单;
  • Tray:实现应用最小化到系统托盘(后台运行),支持点击/右键交互。
实战示例:系统托盘与上下文菜单
javascript 复制代码
const { Tray, Menu, BrowserWindow } = require('electron')
const path = require('path')

function createTray(mainWindow) {
  // 创建托盘图标(推荐使用透明背景的PNG,尺寸32x32)
  const tray = new Tray(path.join(__dirname, 'tray-icon.png'))
  
  // 构建托盘右键菜单
  const contextMenu = Menu.buildFromTemplate([
    { 
      label: '显示窗口', 
      click: () => {
        mainWindow.show() // 显示窗口
        mainWindow.focus() // 聚焦窗口
      }
    },
    { 
      label: '最小化到托盘', 
      click: () => mainWindow.hide() // 隐藏窗口
    },
    { type: 'separator' }, // 分隔线
    { 
      label: '退出', 
      click: () => {
        mainWindow.destroy() // 销毁窗口
        app.quit() // 退出应用
      }
    }
  ])
  
  // 配置托盘
  tray.setToolTip('我的Electron应用') // 鼠标悬停提示
  tray.setContextMenu(contextMenu) // 绑定右键菜单
  
  // 左键点击托盘图标:切换窗口显示/隐藏
  tray.on('click', () => {
    if (mainWindow.isVisible()) {
      mainWindow.hide()
    } else {
      mainWindow.show()
    }
  })
  
  return tray
}

// 在创建主窗口后初始化托盘
let mainWindow = new BrowserWindow(/* 配置 */)
const tray = createTray(mainWindow)

二、渲染进程核心 API(Renderer Process)

渲染进程运行在 Chromium 浏览器环境中,负责 UI 渲染和用户交互,通过预加载脚本与主进程通信。

1. ipcRenderer:渲染进程通信的"发送器"

核心功能 :向主进程发送消息并接收响应,与 ipcMain 配合完成进程间通信。

常用方法与场景
方法 作用 典型场景
ipcRenderer.invoke(channel, data) 发送异步请求并等待响应 调用主进程API(文件操作、系统功能)
ipcRenderer.send(channel, data) 发送消息(无需响应) 通知主进程状态变化(如用户操作)
ipcRenderer.on(channel, listener) 监听主进程发送的消息 接收实时数据(如定时更新、系统事件)
实战示例:完整的进程通信流程
javascript 复制代码
// 预加载脚本(preload.js):安全暴露通信API
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
  // 1. 异步请求-响应(如获取系统信息)
  getSystemInfo: () => ipcRenderer.invoke('system:info'),
  
  // 2. 单向通知(如用户操作日志)
  logUserAction: (action) => ipcRenderer.send('user:action', action),
  
  // 3. 监听主进程推送(如主题切换)
  onThemeChange: (callback) => {
    // 包装回调,避免直接暴露事件对象
    const wrapper = (event, theme) => callback(theme)
    ipcRenderer.on('theme:change', wrapper)
    
    // 返回清理函数(组件卸载时调用)
    return () => ipcRenderer.removeListener('theme:change', wrapper)
  }
})

// 主进程(main.js):处理通信
const { ipcMain, systemPreferences } = require('electron')

// 处理系统信息请求
ipcMain.handle('system:info', async () => {
  return {
    platform: process.platform, // 操作系统(win32/darwin/linux)
    theme: systemPreferences.getColor('window') === '#ffffff' ? 'light' : 'dark'
  }
})

// 处理用户操作日志
ipcMain.on('user:action', (event, action) => {
  console.log('用户操作:', action) // 可写入日志文件
})

// 主进程主动推送主题变化
function notifyThemeChange(theme) {
  mainWindow.webContents.send('theme:change', theme)
}

// 渲染进程(Vue/React组件中):使用API
async function init() {
  // 获取系统信息
  const sysInfo = await window.electronAPI.getSystemInfo()
  console.log('系统信息:', sysInfo)
  
  // 记录用户操作
  window.electronAPI.logUserAction('打开设置页面')
  
  // 监听主题变化(并在组件卸载时清理)
  const cleanup = window.electronAPI.onThemeChange((theme) => {
    document.body.className = theme // 应用主题样式
  })
  
  // 组件卸载时调用清理
  return () => cleanup()
}

2. webFrame:渲染行为的"控制器"

核心功能:控制网页渲染行为,如注入 CSS、修改缩放比例、执行脚本等。

常用方法与场景
方法 作用 典型场景
webFrame.insertCSS(css) 注入全局 CSS 样式 自定义全局主题、覆盖第三方样式
webFrame.setZoomFactor(factor) 设置页面缩放比例 支持缩放功能的应用(如阅读器)
webFrame.executeJavaScript(code) 在页面上下文执行 JS 代码 动态修改页面内容、调用页面方法
实战示例:动态注入主题样式
javascript 复制代码
// 渲染进程(通过预加载脚本暴露)
const { contextBridge, webFrame } = require('electron')

contextBridge.exposeInMainWorld('themeAPI', {
  // 应用暗黑模式
  setDarkMode: () => {
    webFrame.insertCSS(`
      body { background: #1a1a1a !important; color: #fff !important; }
      .button { background: #333 !important; border: 1px solid #444 !important; }
    `)
  },
  // 重置默认样式
  resetStyle: () => {
    // 移除所有注入的CSS(需跟踪注入的样式ID)
    // 实际项目中可通过插入带ID的<style>标签,再移除实现
  }
})

// 渲染进程调用
document.getElementById('darkModeBtn').addEventListener('click', () => {
  window.themeAPI.setDarkMode()
})

三、系统集成 API:与操作系统交互

Electron 提供了一系列与系统深度集成的 API,支持调用原生功能如剪贴板、全局快捷键、电源管理等。

1. shell:系统操作的"快捷方式"

核心功能:调用系统默认程序处理文件、URL 等,如用默认浏览器打开网页、用默认播放器打开视频。

常用方法与场景
方法 作用 典型场景
shell.openExternal(url) 用默认应用打开 URL(网页/邮件等) 打开帮助文档(网页)、发送邮件
shell.openPath(path) 用默认应用打开文件/目录 查看下载的文件、打开日志目录
shell.trashItem(path) 将文件移到回收站 安全删除文件(替代直接删除)
shell.showItemInFolder(path) 在文件管理器中显示文件 下载完成后定位文件位置
实战示例:文件操作集成
javascript 复制代码
const { shell } = require('electron')
const path = require('path')

// 1. 打开帮助网页
async function openHelpDoc() {
  try {
    await shell.openExternal('https://docs.example.com')
  } catch (err) {
    console.error('打开网页失败:', err)
  }
}

// 2. 定位文件在资源管理器中的位置
async function showFileInFolder() {
  const filePath = path.join(app.getPath('downloads'), 'report.pdf')
  try {
    await shell.showItemInFolder(filePath)
  } catch (err) {
    console.error('文件不存在:', err)
  }
}

// 3. 将文件移到回收站
async function deleteToTrash() {
  const filePath = 'path/to/file.txt'
  try {
    await shell.trashItem(filePath)
    console.log('文件已移到回收站')
  } catch (err) {
    console.error('删除失败:', err)
  }
}

2. clipboard:剪贴板的"操作器"

核心功能:读写系统剪贴板,支持文本、HTML、图片等格式。

常用方法与场景
方法 作用 典型场景
clipboard.writeText(text) 写入文本到剪贴板 复制文本内容(如链接、代码)
clipboard.readText() 从剪贴板读取文本 粘贴文本到应用内
clipboard.writeImage(image) 写入图片到剪贴板 复制截图、图片
clipboard.clear() 清空剪贴板 敏感操作后清理剪贴板
实战示例:文本与图片剪贴板操作
javascript 复制代码
const { clipboard, nativeImage } = require('electron')

// 1. 复制文本
function copyTextToClipboard(text) {
  clipboard.writeText(text)
  console.log('已复制到剪贴板:', text)
}

// 2. 粘贴文本
function pasteTextFromClipboard() {
  const text = clipboard.readText()
  console.log('剪贴板内容:', text)
  return text
}

// 3. 复制图片(从文件)
async function copyImageToClipboard(imagePath) {
  const image = nativeImage.createFromPath(imagePath)
  clipboard.writeImage(image)
  console.log('已复制图片到剪贴板')
}

3. globalShortcut:全局快捷键的"注册器"

核心功能 :注册系统级快捷键,即使应用在后台也能响应(如截图工具的 Ctrl+Shift+A)。

注意事项
  • 快捷键需在应用就绪后注册,退出前注销;
  • 避免与系统快捷键冲突(如 Ctrl+S 通常用于保存)。
实战示例:注册全局截图快捷键
javascript 复制代码
const { app, globalShortcut, BrowserWindow } = require('electron')

// 应用就绪后注册快捷键
app.whenReady().then(() => {
  // 注册 Ctrl+Shift+S 快捷键(Windows/Linux)
  const ret = globalShortcut.register('CommandOrControl+Shift+S', () => {
    console.log('触发截图快捷键')
    // 打开截图窗口
    const captureWindow = new BrowserWindow({
      width: 800,
      height: 600,
      frame: false,
      alwaysOnTop: true,
      webPreferences: { preload: path.join(__dirname, 'capture-preload.js') }
    })
    captureWindow.loadFile('screenshot.html')
  })

  if (!ret) {
    console.error('快捷键注册失败(可能已被占用)')
  }
})

// 应用退出前注销所有快捷键
app.on('will-quit', () => {
  globalShortcut.unregisterAll() // 注销所有全局快捷键
})

四、安全最佳实践:API 使用的"红线"

Electron 应用的安全风险主要来自渲染进程对系统 API 的滥用,需严格遵循以下原则:

  1. 禁用 nodeIntegration,启用 contextIsolation

    javascript 复制代码
    // 主进程窗口配置(必须遵守)
    new BrowserWindow({
      webPreferences: {
        nodeIntegration: false, // 禁用渲染进程直接访问Node.js
        contextIsolation: true, // 启用上下文隔离(隔离渲染进程与主进程)
        preload: path.join(__dirname, 'preload.js') // 仅通过预加载脚本通信
      }
    })
  2. 通过 contextBridge 安全暴露 API

    禁止直接暴露 ipcRenderer 或主进程模块,仅暴露必要的方法:

    javascript 复制代码
    // 正确示例:暴露有限方法
    contextBridge.exposeInMainWorld('electronAPI', {
      openFile: () => ipcRenderer.invoke('dialog:openFile')
    })
    
    // 错误示例:暴露完整ipcRenderer(风险)
    contextBridge.exposeInMainWorld('ipcRenderer', ipcRenderer) // ❌
  3. 限制 preload.js 的权限

    预加载脚本应仅作为通信中介,避免包含复杂业务逻辑或敏感操作。

  4. 配置内容安全策略(CSP)

    在 HTML 中限制资源加载,防止 XSS 攻击:

    html 复制代码
    <meta http-equiv="Content-Security-Policy" 
      content="default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline';">

五、API 模块速查表

功能分类 核心模块/API 关键方法/配置
应用生命周期 app whenReady()quit()getPath()
窗口管理 BrowserWindow 尺寸配置、loadFile()show()
进程通信 ipcMain/ipcRenderer handle()invoke()send()
系统对话框 dialog showOpenDialog()showMessageBox()
菜单与托盘 Menu/Tray buildFromTemplate()setContextMenu()
系统集成 shell/clipboard/globalShortcut openExternal()writeText()register()
渲染控制 webFrame insertCSS()setZoomFactor()

通过合理组合这些 API,可实现从简单窗口到复杂系统工具的全场景应用开发。建议结合 Electron 官方文档 深入学习每个模块的细节,同时始终将安全最佳实践贯穿开发全过程。

相关推荐
秉承初心21 分钟前
Node.js 开发 JavaScript SDK 包的完整指南(AI)
开发语言·javascript·node.js
上单带刀不带妹38 分钟前
ES6 中的 Proxy 全面讲解
前端·ecmascript·es6·proxy
11054654011 小时前
37、需求预测与库存优化 (快消品) - /供应链管理组件/fmcg-inventory-optimization
前端·信息可视化·数据分析·js
nunumaymax2 小时前
在图片没有加载完成时设置默认图片
前端
OEC小胖胖2 小时前
【React 设计模式】受控与非受控:解构 React 组件设计的核心模式
前端·react.js·设计模式·前端框架·web
你怎么知道我是队长2 小时前
C语言---编译的最小单位---令牌(Token)
java·c语言·前端
一枚前端小能手3 小时前
🔥 Vue状态管理越写越乱,Pinia拯救了我
前端
cloudcruiser4 小时前
Apache HTTP Server:深入探索Web世界的磐石基石!!!
前端·其他·http·apache
一个专注api接口开发的小白4 小时前
手把手教程:使用 Postman 测试与调试淘宝商品详情 API
前端·数据挖掘·api
芜青4 小时前
JavaScript手录18-ajax:异步请求与项目上线部署
开发语言·javascript·ajax