Electron 主进程 渲染进程怎么通信

163 阅读3分钟

1、先看下纳米ai给的总结

cgi-bin_mmwebwx-bin_webwxgetmsgimg_&MsgID=1030677872998780304&skey=@crypt_13efb6fd_744cadad7b57a4711a295571b4a736bc&mmweb_appid=wx_webfilehelper.jpeg

2、渲染进程=>主进程(单项通信)

概述:在渲染器进程中ipcRenderer.send发送消息,在主进程中使用ipcMain.on接收消息

 //index.html文件 渲染进程
 <body>
    <button id="btn">发送消息</button>
    <script>
      document.getElementById('btn').onclick = function () {
        toRenderVersions.putData('发送给主线程的数据');
      };
    </script>
  </body>
//preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('toRenderVersions', {
  //对外暴露一个toRenderVersions全局变量,渲染进程可以获取
  putData: (data) => {
    //向渲染进程发送消息
    ipcRenderer.send('putData', data);
  },
});
//main.js
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('node:path'); //node的path方法

function createWindow() {
  const win = new BrowserWindow({
    //创建窗口
    width: 800,
    height: 600,
    autoHideMenuBar: true, //隐藏默认配置菜单
    x: 0,
    y: 0, //在什么位置打开
    alwaysOnTop: false, //一直置顶,不被遮挡
    webPreferences: {
      // 网页功能设置
      preload: path.join(__dirname, './preload.js'), //__dirname 字符串指向当前正在执行的脚本的路径(在本例中,它指向你的项目的根文件夹)。path.join API 将多个路径联结在一起,创建一个跨平台的路径字符串。
    },
  });

  ipcMain.on('putData', getData);

  // win.loadURL('https://blog.csdn.net/m0_56772756?type=blog'); //加载远程页面
  win.loadFile('./pages/index.html'); //加载远程页面
}

const getData = (event, arg) => {
  console.log('主线程接受到消息>>', arg);
};

3、主进程<=>渲染进程(双向通信)

概述:渲染进程通过ipcRenderer.invoke 发送消停,主进程使用ipcMain.handle接收并处理消息。

//index.html文件 渲染进程
<body>
    <button id="btn">发送消息</button>
    <script>
      document.getElementById('btn').onclick = async () => { //ipcRender.invoke的返回值是Promise实例
        const data = await toRenderVersions.getData('参数'); //调用preload暴露的getData方法
        console.log(data);
      };
    </script>
</body>
//preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('toRenderVersions', {
  getData: (data) => {
    //接收渲染进程的消息
    return ipcRenderer.invoke('getMainData',data); //调用,渲染进程与主进程的双向通信
  },
});
//main.js 主进程
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('node:path'); //node的path方法

function createWindow() {
    const win = new BrowserWindow({
        //创建窗口
        width: 800,
        height: 600,
        autoHideMenuBar: true, //隐藏默认配置菜单
        x: 0,
        y: 0, //在什么位置打开
        alwaysOnTop: false, //一直置顶,不被遮挡
        webPreferences: {
          // 网页功能设置
          preload: path.join(__dirname, './preload.js'), //__dirname 字符串指向当前正在执行的脚本的路径(在本例中,它指向你的项目的根文件夹)。
          //path.join API 将多个路径联结在一起,创建一个跨平台的路径字符串。
        },
      });
  ipcMain.handle('getMainData', getData);

  // win.loadURL('https://blog.csdn.net/m0_56772756?type=blog'); //加载远程页面
  win.loadFile('./pages/index.html'); //加载远程页面
}

const getData = (event, arg) => {
  console.log(arg) //'参数'
  return 'hello world';
};

4、主进程=>渲染进程(单向通信)

概述:主进程通过win.webContents.send发送消息,渲染进程通过ipcRenderer.on接收消息

//main.js
const { app, BrowserWindow, ipcMain } = require('electron');
const path = require('node:path'); //node的path方法

function createWindow() {
  const win = new BrowserWindow({
    //创建窗口
    width: 800,
    height: 600,
    autoHideMenuBar: true, //隐藏默认配置菜单
    x: 0,
    y: 0, //在什么位置打开
    alwaysOnTop: false, //一直置顶,不被遮挡
    webPreferences: {
      // 网页功能设置
      preload: path.join(__dirname, './preload.js'), //__dirname 字符串指向当前正在执行的脚本的路径(在本例中,它指向你的项目的根文件夹)。
      //path.join API 将多个路径联结在一起,创建一个跨平台的路径字符串。
    },
  });

  win.webContents.send('message', '你好啊'); //发送给渲染进程的数据

  // win.loadURL('https://blog.csdn.net/m0_56772756?type=blog'); //加载远程页面
  win.loadFile('./pages/index.html'); //加载远程页面
}
//preload.js
const { contextBridge, ipcRenderer } = require('electron');

contextBridge.exposeInMainWorld('toRenderVersions', {
  //对外暴露一个toRenderVersions全局变量,渲染进程可以获取
  getMsg: (callback) => {
    return ipcRenderer.on('message', callback);
  },
});
//index.html
<script>
  window.onload = () => {
    toRenderVersions.getMsg((e, data) => {
      console.log(data); //'你好啊'
    });
  };
</script>

5、渲染进程 => 渲染进程,不能直接通信,需要通过主进程传递数据

image.png