进程间通信 (IPC) 是在 Electron 中构建功能丰富的桌面应用程序的关键部分之一。 由于主进程和渲染器进程在 Electron 的进程模型具有不同的职责,因此 IPC 是执行许多常见任务的唯一方法,例如从 UI 调用原生 API 或从原生菜单触发 Web 内容的更改。
在 Electron 中,进程使用 ipcMain 和 ipcRenderer 模块,通过开发人员定义的“通道”传递消息来进行通信。
在本文中,我们使用vue3+vite+elctron做演示,将介绍一些基本的 IPC 模式,并提供具体的示例。您可以将这些示例作为您应用程序代码的参考。
npm init vite
npm install
npm install electron --save-dev
"main": "main.js",
"scripts": {
"dev": "vite",
"start": "electron ."
}
npm run dev
npm run start
从主进程发送到渲染器进程,指定一个渲染器接收消息。 消息通过 WebContents 实例发送到渲染器进程。
在下面的示例中,我们将在主进程创建一个菜单,点击菜单事件后,发送消息到渲染器进程,渲染器进程接受到消息后,做弹窗操作。
// main.js
const {app,BrowserWindow,Menu} = require('electron')
const path = require('path')
//主进程创建窗口方法
const createWindow = () => {
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
//打开渲染页面
win.loadURL('http://localhost:5173')
//创建自定义菜单
const template = [{
label: '文件',
submenu: [{
label: '新建',
accelerator: 'CmdOrCtrl+N',
click() {
// 这里点击'新建'菜单向渲染进程发送消息
win.webContents.send('update-isShow')
}
}
]
}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
}
//在应用准备就绪时调用创建窗口方法函数
app.whenReady().then(() => {
createWindow()
})
// preload.js
const { contextBridge, ipcRenderer} = require('electron')
//桥接渲染进程与主进程的点击'新建'菜单方法
const openDialog = (callback) => {
ipcRenderer.on('update-isShow', callback)
}
contextBridge.exposeInMainWorld('electronAPI', {openDialog})
// renderer.js
// vue页面监听消息操作
window.electronAPI.openDialog(()=>{
//...这里打开弹窗
})
从渲染器进程代码调用主进程模块并等待结果。 通过 ipcRenderer.invoke 与 ipcMain.handle 搭配使用来完成。
在下面的示例中,我们将从渲染器进程发送一个网址到主进程,主进程拿到网址,打开网址截屏,获取图片并返回图片路径。
// renderer.js
// vue页面触发新增网站按钮事件
const handleSubmit = async () => {
const result = await window.electronAPI.sendUrl(url)
//拿到主进程返回的结果,做添加处理
console.log(result)
}
// preload.js
const { contextBridge, ipcRenderer} = require('electron')
//桥接渲染进程与主进程的新增网站方法
const sendUrl = async (url) => {
const result = await ipcRenderer.invoke('get-url-event', url)
return result
}
contextBridge.exposeInMainWorld('electronAPI', {sendUrl})
// main.js
const { ipcMain} = require('electron')
//主进程使用shell打开网站
ipcMain.handle('get-url-event', async (event, url) => {
const result = await getSource(url)
return result
})
//获取网站截屏图片
const getSource = (url) => {
return new Promise((resolve, reject) => {
//...这里处理逻辑,并返回结果
resolve(base64)
})
}
从渲染器进程发送到主进程,使用 ipcRenderer.send 发送消息,然后使用 ipcMain.on 接收。
在下面的示例中,我们将从渲染器进程发送一个网址到主进程,主进程拿到网址,打开网址。
// renderer.js
// vue页面触发打开网站按钮事件
const handleOpen = (url) => {
window.electronAPI.openUrl(url)
}
// preload.js
const { contextBridge, ipcRenderer} = require('electron')
//桥接渲染进程与主进程的打开网站方法
const openUrl = (url) => {
ipcRenderer.send('open-url-event', url)
}
contextBridge.exposeInMainWorld('electronAPI', {openUrl})
// main.js
const { ipcMain, shell} = require('electron')
//主进程使用shell打开网站
ipcMain.on('open-url-event', (event, url) => {
shell.openExternal(url)
})
通过vue3+elctron实现一个基础的桌面端应用——收藏夹功能。使用了部分vue3的基本功能及方法,了解Electron的一下API的使用,开发中的常用的插件及依赖的使用方法。
npm install
npm run dev
npm run start