进程间通信
为了将Electron的不同类型的进程桥接在一起,我们需要使用被称为预加载preload的脚本
| 可用的API | 详细信息 | 
|---|---|
| Electron模块 | 渲染进程模块 | 
| Node.js模块 | events、timers、url | 
| Pollfilled的全局模块 | Buffer、process、clearImmediate、setImmediate | 
preload脚本Demo
创建一个preload.js
然后在需要的进程里加载
注意:可以用的api在上面有说明, 在文档可以看一下这些模块有什么属性/方法: https://www.electronjs.org/zh/docs/latest/api/process#processversionschrome-%E5%8F%AA%E8%AF%BB
preload.js
const { contextBridge } = require('electron');
const versions = contextBridge.exposeInMainWorld('versions', {
    node: process.versions.node,
    chrome: process.versions.chrome,
    electron: process.versions.electron
});
module.exports = versions;在main文件中加载
const { app, BrowserWindow } = require('electron');
const path  = require('path');
function createWindow () {
    let win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js')
        }
    })
    win.loadFile('index.html');
    win.webContents.openDevTools();
    return win;
}    注意: 在index.html页面,我们就可以使用window.versions来访问或执行对应的方法了
IPC通信
Electron 的 IPC(Inter-Process Communication,进程间通信)机制允许主进程和渲染进程之间的双向通信,是构建功能丰富的桌面应用的关键
- 主进程使用 ipcMain:监听和处理来自渲染进程的消息。]
 - 渲染进程使用 ipcRenderer:向主进程发送消息或接收回复。
 
单向进程
主要两个方法
ipcRenderer.send(发送) 和ipcMain.on(接收)
demo: 修改窗口标题(单向进程)
index.html 的script
const demo2 = function() {
    let btn = document.querySelector('.demo2 button');
    let input = document.querySelector('.demo2 input');
    btn.addEventListener('click', () => {
        let title = input.value;
        window.electron.setTitle(title)
    })
}preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electron', {
    setTitle(title) {
        return ipcRenderer.send('set-title', title)
    }
})main.js
const { app, BrowserWindow, ipcMain } = require('electron');
// ...
// app是BrowserWindow的一个实例
app.on('ready', () => {
    let parent = createWindow();
    // createChildWindow(parent);
    ipcMain.on('set-title', (event, title) => {
        console.log('title, ', title)
        const webContents = event.sender;
        // 获取渲染进程(当前渲染的窗口)实列
        const win = BrowserWindow.fromWebContents(webContents);
        // 修改窗口
        win.setTitle(title);
    })
})ipcMain的event说明: https://www.electronjs.org/zh/docs/latest/api/structures/ipc-main-event
双向通信
双向通信 - 从渲染器进程到主进程,再从主进程到渲染进程
主要的两个方法: ipcRenderer.invoke(发送) 和ipcMain.handle(响应)
写法都差不多,调用的api不同,多了一个返回值而已
写入文件内容并响应(demo)
index.html
btn.addEventListener('click', async() => {
    let content = input.value || 'string';
    const size = await window.electron.handleWriteFile(content);
    console.log('响应值', size )
})preload.js
handleWriteFile(content) {
    console.log('ipcrenderer')
    console.log(content, 'content')
    return ipcRenderer.invoke('write-file', content);
}main.js
const { app, BrowserWindow, ipcMain } = require('electron');
const path  = require('path');
const fs = require('fs');
function createWindow () {
    let win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js')
        }
    })
    win.loadFile('index.html');
    win.webContents.openDevTools();
    return win;
}
app.on('ready', () => {
    ipcMain.handle('write-file', async(event, content) => {
        await fs.promises.writeFile('test.txt', content);
        const textFile = await fs.promises.stat('test.txt');
        // 主要是这里要响应,渲染进程就可以接收到了。
        return textFile.size;
    });
    createWindow();
})主进程向渲染进程通信
通过win.webContents.send();
main.js
const { app, BrowserWindow, ipcMain } = require('electron');
function createWindow () {
    let win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: path.join(__dirname, 'preload.js')
        }
    })
    win.loadFile('index.html');
    win.webContents.openDevTools();
    return win;
}
app.on('ready', () => {
    const win = createWindow();
    let count = 0;
    win.webContents.send('update-count', count);
    setInterval(() => {
        count++;
        win.webContents.send('update-count', count);
    }, 1000);
})
preload.js
const { contextBridge, ipcRenderer } = require('electron');
contextBridge.exposeInMainWorld('electron', {
    updateCounter(callback) {
        return ipcRenderer.on('update-count', callback)
    }
})index.html
window.electron.updateCounter((event, count) => {
    console.log(count, 'count')
})