切换主题
二、进程通信
一、渲染器进程到主进程(单向)
预加载脚本
注册
apiKey
apiKey
string - 将 API 注入到窗口
的键。 API 将可通过window[apiKey]
访问。api
any - 你的 API可以是什么样的以及它是如何工作的相关信息如下。
jscontextBridge.exposeInMainWorld('electronAPI', { setTitle: (title) => ipcRenderer.send('set-title', title) })
渲染进程
通过
window
属性,调用预加载脚本的方法
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Hello World!</title>
</head>
<body>
Title: <input id="title"/>
<button id="btn" type="button">Set</button>
<script src="./renderer.js"></script>
</body>
</html>
renderer
js
const setButton = document.getElementById('btn')
const titleInput = document.getElementById('title')
setButton.addEventListener('click', () => {
const title = titleInput.value
window.electronAPI.setTitle(title)
})
此时,渲染进程使用预加载脚本向主进程发送了字符串
主进程
应用程序加载好后,在whenReady中加载预加载脚本传递过来的参数
jsfunction handleSetTitle (event, title) { const webContents = event.sender const win = BrowserWindow.fromWebContents(webContents) win.setTitle(title) } app.whenReady().then(() => { ipcMain.on('set-title', handleSetTitle) createWindow() })
二、渲染器进程到主进程(双向)
说明
双向 IPC 的一个常见应用是从渲染器进程代码调用主进程模块并等待结果。 这可以通过将 ipcRenderer.invoke
与 ipcMain.handle
搭配使用来完成。
js
async function handleFileOpen () {
const { canceled, filePaths } = await dialog.showOpenDialog({})
if (!canceled) {
return filePaths[0]
}
}
app.whenReady().then(() => {
ipcMain.handle('dialog:openFile', handleFileOpen)
createWindow()
})
js
const { contextBridge, ipcRenderer } = require('electron')
contextBridge.exposeInMainWorld('electronAPI', {
openFile: () => ipcRenderer.invoke('dialog:openFile')
})
js
btn.addEventListener('click', async () => {
const filePath = await window.electronAPI.openFile()
filePathElement.innerText = filePath
})
三、主进程到渲染进程
html
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<!-- https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP -->
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
<title>Menu Counter</title>
</head>
<body>
Current value: <strong id="counter">湖北师范大学</strong>
<script src="./renderer.js"></script>
</body>
</html>
js
function createWindow() {
const mainWindow = new BrowserWindow({
webPreferences: {
preload: path.join(__dirname, 'preload.js')
}
})
mainWindow.loadFile('index.html').then(() => {
mainWindow.webContents.send("counter-value", "黄达全")
})
}
js
const { contextBridge, ipcRenderer } = require('electron/renderer')
contextBridge.exposeInMainWorld('electronAPI', {
onUpdateCounter: (callback) => ipcRenderer.on('counter-value', (_event, value) => callback(value))
})
js
const counter = document.getElementById('counter')
window.electronAPI.onUpdateCounter((value) => {
const oldValue = counter.innerText
console.log(oldValue);
setTimeout(() => {
counter.innerText = value
console.log(value);
}, 3000);
})
四、渲染器进程到渲染器进程
说明
没有直接的方法可以使用 ipcMain
和 ipcRenderer
模块在 Electron 中的渲染器进程之间发送消息
不过有俩种替代方案
- 将主进程作为渲染器之间的消息代理。 这需要将消息从一个渲染器发送到主进程,然后主进程将消息转发到另一个渲染器。
- 从主进程将一个
MessagePort
传递到两个渲染器。 这将允许在初始设置后渲染器之间直接进行通信。