引入
electron中的渲染进程与主进程之间的数据交互需要利用ipc通信,互相订阅/通知来实现,我们不妨封装一个通用事件广播,利用自定义的事件名称来让主进程遍历窗口挨个推送对应内容,来实现事件的广播。
demo项目地址
实现思路
- 1.在主进程中添加一个通用的handle,它接受一个特定类型的参数,里面包含事件名称,和对应的传输数据
- 2.在handle中遍历已有的所有窗口,挨个触发窗口的webContents.send方法进行通知【实现广播】
- 3.需要接受通知的窗口【页面】订阅对应事件,进行后续的逻辑处理
实现步骤
1.在全局声明文件中添加通用事件对象的声明
- types\global.d.ts
/** 一些全局的对象补充声明 */
export {};
declare global {
// 通用事件对象
interface EventInfo {
channel: string; // 对应渲染层监听管道
body: string; // JSON序列化后的消息内容
}
}
2.主进程添加事件转发、广播逻辑
- electron\main\index.ts
/**事件广播通知 */
ipcMain.handle(
"event-broadcast",
(event, eventInfo: EventInfo) => {
// 遍历window执行
for (const currentWin of BrowserWindow.getAllWindows()) {
// 注意,这里控制了发送广播的窗口,不触发对应事件,如果需要自身也触发的话,删除if内的逻辑即可
if (event) {
const webContentsId = currentWin.webContents.id;
if (webContentsId === event.sender.id) {
continue;
}
}
currentWin.webContents.send(eventInfo.channel, eventInfo.body);
}
}
);
3.electron工具类中添加对应方法,用于通知主进程进行广播
- src\utils\electronUtils.ts
/**
* 事件广播
* @param enevntInfo 事件对象
*/
export function eventBroadcast(enevntInfo: EventInfo) {
ipcRenderer.invoke("event-broadcast", enevntInfo);
}
测试事件广播
1.我们在demo/index.vue中补充点击事件:
- src\components\demo\Index.vue
<template>
<li><el-button @click="eventBroadcast">测试事件广播</el-button></li>
</template>
<script>
// 事件广播测试
function eventBroadcast(){
electronUtils.eventBroadcast({channel:"test-event-broadcast",body:JSON.stringify({name:'编程小龙',value:'hello'})});
}
</script>
2.在helloWord页面,监听 test-event-broadcast 事件
<script>
import { onMounted, ref, reactive, onUnmounted } from "vue";
import { ipcRenderer } from "electron";
// 添加监听
onMounted(() => {
ipcRenderer.on("test-event-broadcast",(e,data)=>{
console.log("监听到广播内容:");
console.log(JSON.parse(data));
});
});
// 移除监听
onUnmounted(() => {
ipcRenderer.removeListener("test-event-broadcast",()=>{});
});
</script>
3.测试效果如下:
1.新建了两个helloword页面的窗口
2.index页面中发送test-event-broadcast名称的事件,两个helloword窗口都能收到事件通知