electron的进程间通信(小结)

技术文档(参考文档):https://www.electronjs.org/zh/docs/latest/tutorial/ipc

进程间信号传递

1. 渲染器进程到主进程(单向)

(1)主进程,用ipcMain.on()进行监听:

// main.js
const { app, BrowserWindow, ipcMain } = require('electron/main')
...
 ipcMain.on('set-title', handleSetTitle)

function handleSetTitle (event, title) {
  console.log(title)  // 在node.js控制台打印
}

(2)通过预加载脚本暴露 ipcRenderer.send。

// preload.js
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
  setTitle: (title) => ipcRenderer.send('set-title', title)
})

(3)渲染器进程:从预加载脚本中暴露的 window.electronAPI发送信号。

// 渲染器页面,render/src/index.html或者render/src/index.vue
  const title = ‘标题’
  window.electronAPI.setTitle(title)

2.渲染器进程到主进程(双向)

双向通信应用场景:从渲染器进程代码调用主进程模块并等待结果
双向通信的流程:和单向类似,使用的方法名有区别。

(1)主进程,用ipcMain.handle()进行监听:

// main.js
const { app, BrowserWindow, ipcMain, dialog } = require('electron/main')
...
// 1. 渲染器到主进程(单向):主进程在监听
 ipcMain.on('set-title', handleSetTitle)

...

// 2. 渲染器到主进程(双向):主进程在监听
 ipcMain.handle('dialog:openFile', handleFileOpen)

async function handleFileOpen () {
  const { canceled, filePaths } = await dialog.showOpenDialog()
  if (!canceled) {
    return filePaths[0]
  }
}

(2)通过预加载脚本暴露 ipcRenderer.invoke。

// preload.js
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
// 1. 渲染器到主进程(单向)
  setTitle: (title) => ipcRenderer.send('set-title', title)
// 2. 渲染器到主进程(双向)
  openFile: () => ipcRenderer.invoke('dialog:openFile')
})

(3)渲染器进程:从预加载脚本中暴露的 window.electronAPI发送信号。

// 渲染器页面,render/src/index.html或者render/src/index.vue
// 2. 渲染器到主进程(双向)
  const filePath = await window.electronAPI.openFile()  // 此处必须要await

3. 主进程到渲染器进程

(1)主进程,使用 webContents 模块发送消息:

// main.js
const { app, BrowserWindow, ipcMain, dialog } = require('electron/main')
...
// 1. 渲染器到主进程(单向):主进程在监听
 ipcMain.on('set-title', handleSetTitle)
...
// 2. 渲染器到主进程(双向):主进程在监听
 ipcMain.handle('dialog:openFile', handleFileOpen)
...

// 3. 主进程到渲染器:主进程发出信号。
mainWindow.webContents.send('update-counter', 1),

(2)通过预加载脚本暴露 ipcRenderer.on

// preload.js
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
// 1. 渲染器到主进程(单向)
  setTitle: (title) => ipcRenderer.send('set-title', title)
// 2. 渲染器到主进程(双向)
  openFile: () => ipcRenderer.invoke('dialog:openFile')
// 3. 主进程到渲染器
  onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value))
})

(3)渲染器进程:从预加载脚本中暴露的 window.electronAPI 监听信号。

// 渲染器页面,render/src/index.html或者render/src/index.vue

// 1. 渲染器到主进程(单向):渲染器发出信号
  const title = ‘标题’
  window.electronAPI.setTitle(title)

// 2. 渲染器到主进程(双向):渲染器发出信号,并等待主进程返回结果
const filePath = await window.electronAPI.openFile()  // 此处必须要await

// 3. 主进程到渲染器(单向):渲染器在监听
window.electronAPI.onUpdateCounter((value) => {
  console.log(value)
})
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。