Electron学习笔记之渲染进程间通信

1,153 阅读2分钟

渲染进程与渲染进程通信

渲染进程间通信.png

由于渲染进程之间没有办法直接通信,所以得借助主进程来通信

  • 方法一:通过localStorage.setItem(key,value)localStorage.getItem(key)传值 全局的main.js
require("./路径/ipcMain");

index.html

<button id="btn">打开新窗口</button>
<script src="./ipcRenderer/index.js"></script>

index.js

const { ipcRenderer } = require("electron");
window.onload = () => {

    var btnDom = document.querySelector("#btn");
    btnDom.onclick = () => {

        //设置一个值
        localStorage.setItem("id", 1234);
        ipcRenderer.send("openNews")
    }
}

点击按钮之后,先存一个idlocalStorage,接着渲染进程主进程发起通信,触发openNews方法
ipcMain.js

const { BrowserWindow,ipcMain} = require("electron");
const path = require("path");

ipcMain.on("openNews",()=>{
    const mainWindow = new BrowserWindow({
        width: 400,
        height: 300,
        webPreferences: {
            nodeIntegration: true,  //开启渲染进程中使用nodejs
            enableRemoteModule:true  //启用Remote模块
        }
    });
    mainWindow.loadFile(path.join(__dirname, "../news.html"));
})

主进程接收到请求之后,执行openNews,以news.html为模板创建一个新的窗口
news.html

<script src="./ipcRenderer/news.js"></script>

news.js

var id=localStorage.getItem("id");
console.log(id)

新窗口创建之后执行localStorage.getItem("id")获取并输出id

localstorage.png

  • 方法二:通过渲染进程主进程传值,在由主进程通知渲染进程并传值

index.html 是同样的代码

// index.html
<button id="btn">打开新窗口</button>
<script src="./ipcRenderer/index.js"></script>

index.js 做一点点修改

// index.js
const { ipcRenderer } = require("electron");
window.onload = () => {

    var btnDom = document.querySelector("#btn");
    btnDom.onclick = () => {

        // 设置一个值
        // localStorage.setItem("id", 1234);
        ipcRenderer.send("openNews", 1234);
    }
}

ipcMain.js
1)收到ipcRenderer.js后,
2)创建一个新的窗口newsWindow
3)新窗口加载news.html文件,
4)监听新窗口加载完成后,
5)给渲染进程发送消息

const { BrowserWindow,ipcMain} = require("electron");
const path = require("path");

ipcMain.on("openNews",(event,data)=>{
    console.log(data)
    const newsWindow = new BrowserWindow({
        width: 400,
        height: 300,
        webPreferences: {
            nodeIntegration: true,  //开启渲染进程中使用nodejs
            contextIsolation:false, //开启渲染进程中使用nodejs    In Electron 12, the default will bechanged to `true  
            enableRemoteModule:true  //启用Remote模块
        }
    });
    newsWindow.loadFile(path.join(__dirname, "../news.html"));
    // 监听新窗口加载
    newsWindow.webContents.on('did-finish-load',(event) => { 
        newsWindow.webContents.send("toNews",data);
    })
})

news.js

const { ipcRenderer } = require("electron");
ipcRenderer.on("toNews",(e,data)=>{
    console.log(data)
})

然后主进程接收到消息后打印1234,渲染渲染进程打印1234 通信1.png

接着就是往回传值了
news.js

// var id=localStorage.getItem("id");
// console.log(id);
const { ipcRenderer } = require("electron");
ipcRenderer.on("toNews",(e,data)=>{
    console.log(data);
})
window.onload = () => {
    var btnDom = document.querySelector("#btn");
    btnDom.onclick = () => {
        ipcRenderer.send("runIndexFn","this is news html");
    }
}

点击btn,渲染进程给主进程发消息,触发runIndexFn方法,并发送this is news html

ipcMain.js
不属于同一个主进程的渲染进程不能直接监听发送消息,要获取对应主进程的id后,对应id的窗口才可以发送
BrowserWindow.fromId(indexId)找到对应的窗口,对应的窗口,再发送消息

const { BrowserWindow,ipcMain} = require("electron");
const path = require("path");

let indexId;  //index渲染进程的Id

ipcMain.on("openNews",(event,data)=>{
    // 打开时获取当前窗口的id
    indexId=BrowserWindow.getFocusedWindow().id;

    console.log("indexId:",indexId);
    const newsWindow = new BrowserWindow({
        width: 400,
        height: 300,
        webPreferences: {
            nodeIntegration: true,  //开启渲染进程中使用nodejs
            contextIsolation:false, //开启渲染进程中使用nodejs    In Electron 12, the default will bechanged to `true         
            enableRemoteModule:true  //启用Remote模块
        }
    });
    newsWindow.loadFile(path.join(__dirname, "../news.html"));
    newsWindow.webContents.on('did-finish-load',(event) => { 

        newsWindow.webContents.send("toNews",data);
    })
    let newsId=BrowserWindow.getFocusedWindow().id;
    console.log("newsId:",newsId);

})


ipcMain.on("runIndexFn",(e,data)=>{
    console.log(data)
    console.log(indexId)
    //获取index对应的BrowserWindow
    let mainWin = BrowserWindow.fromId(indexId);
    mainWin.webContents.send("toIndex",data);
})

index.js

const { ipcRenderer } = require("electron");
window.onload = () => {

    var btnDom = document.querySelector("#btn");
    btnDom.onclick = () => {
        ipcRenderer.send("openNews","1234");
    }
}

//接收主进程传过来的值   主进程里面的数据来源于news这个渲染进程
ipcRenderer.on("toIndex",(event,data)=>{
    console.log(data);
})

3B(F0S0%F80QW42SDRYNWFD.png

最后,这样就实现了渲染进程间的通信,让我想起来酷狗的那个,弹出来的播放窗口😏好像有点这样回事