当前位置: 首页 > news >正文

electron框架(3.0)主程序与桥梁与渲染,以及之间的通信

每个页面程序通过渲染和主进程通信,主进程根据需求调用Native Api来实现功能。

实际,每个页面和主程序通信时,需要建个桥梁来管理它们的通信,preload.js(自己创建),来管理实现通信

----创建preload.js定义桥梁js:

----关于主程序与渲染层的通信:

写入/传入:send->on   读取:invoke->handle   (预加载脚本 / 桥梁->主进程)

详细解析:
  1. send 和 on 的关系(主进程 <---> 渲染进程):        简易通信不需要返回值
    • send 是发送消息的动作。
    • on 是接收消息的动作。
    • 渲染进程通过 ipcRenderer.send 发送消息,主进程通过 ipcMain.on 接收消息。反之,主进程也可以通过 event.sender.send 向渲染进程发送消息,渲染进程通过 ipcRenderer.on 接收。
  2. invoke 和 handle 的关系(渲染进程 ---> 主进程): 处理异步操作,有返回值        
    • invoke 是发送请求并期望响应的动作。
    • handle 是处理请求并返回响应的动作。
    • 渲染进程通过 ipcRenderer.invoke 发送请求,主进程通过 ipcMain.handle 处理请求并返回结果
 总结:
  • send/on:适用于简单的事件驱动通信,不需要返回值。
  • invoke/handle:适用于需要返回值或处理异步操作的场景,更加现代化和灵活
 main.js(主程序)里的代码:
const {app, BrowserWindow,ipcMain} = require('electron')
const path = require('path')
const fs = require('fs')

//写入文件
function writeFile(_, data) {
    fs.writeFileSync('D:/hello.txt', data)
}
//读取文件
function readFile() {
    const res = fs.readFileSync("D:/hello.txt").toString()
    return res
}

function createWindow() {
    //当app准备好后,执行createWindow创建窗口
    const win = new BrowserWindow({
        width: 800,//窗口宽度
        height: 600,//窗口高度
        autoHideMenuBar: true,//自动隐藏菜单档
        alwaysOnTop: true,//置顶
        webPreferences: {  //在main.js中定义preload.js为桥梁
            preload: path.resolve(__dirname, './preload.js')

        }
    })
    ipcMain.on('file-save', writeFile)
    ipcMain.handle('file-read', readFile)
    //引入页面
    win.loadFile('./pages/index/index.html')
    win.openDevTools()  //自动打开调试窗口
    console.log("main.js里的main.js")
}

app.on('ready', () => {
    createWindow()
    //兼容核心代码1
    app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) createWindow()
    })

})
preload.js(桥梁)里的代码 :
const {contextBridge, ipcRenderer} = require('electron')
contextBridge.exposeInMainWorld('myAPI', {
    version: process.version,
    saveFile: (data) => {
        ipcRenderer.send('file-save', data)
    },
    readFile() {
        //返回的是一个primise的返回值
        return ipcRenderer.invoke('file-read')
    }
})
render.js(渲染)里的代码:
const btn1 = document.getElementById("btn1")
const btn2 = document.getElementById("btn2")
const btn3 = document.getElementById("btn3")
const input = document.getElementById("inp")
btn1.onclick = () => {
    alert(myAPI.version)
}
btn2.onclick = () => {
    myAPI.saveFile(input.value)
}
btn3.onclick = async() => {
    const res = await myAPI.readFile()
    alert(res)
}
html的代码:
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'">
    <title>这里是index页面</title>
</head>

<body>
<h1>欢迎学习Electron开发!!!</h1>
<button id="btn1">点我</button>
<hr/>
<input type="text" id="inp"/>
<button id="btn2">向D盘写入hello.txt</button>
<hr>
<button id="btn3">读取hello.txt的内容</button>
</body>

<script type="text/javascript" src="./render.js"></script>
</html>

包结构:

相关文章:

  • 【实战篇】exists语法解析
  • 【QT 多线程示例】两种多线程实现方式
  • 用Java写斗地主前期工作的一些小想法
  • 【商城实战(44)】商城实战避坑指南:从问题排查到经验升华
  • 回顾一下-笔记
  • 【IDEA中配置Maven国内镜像源】
  • Java设计模式之模板方法模式
  • 蓝桥杯国赛子串2023动态规划,暴力
  • 从WebRTC到嵌入式:EasyRTC如何借助大模型提升音视频通信体验
  • Jmeter使用之http请求默认值
  • Sqoop框架调研
  • Unity Shader 学习16:全局光照 概念理解
  • 机械革命蛟龙16pro玩游戏闪屏
  • flutter本地运行web端图片跨域解决
  • jmeter 循环控制器遍历列表中的数据
  • 网络安全 | 什么是威胁情报?
  • 【数学建模】灰色关联分析模型详解与应用
  • OpenCV图像拼接(5)用于计算一组图像的特征点和描述符的函数computeImageFeatures()
  • Flutter小白零基础入门到高级项目实战全集
  • 移动笔试丨中国移动笔试2025届笔试考什么?运营商春招攻略、考点技巧|附真题秘籍、题型介绍、面试攻略、求职建议
  • “自己生病却让别人吃药”——抹黑中国经济解决不了美国自身问题
  • 外交部:欢迎外国朋友“五一”来中国
  • 新剧|反谍大剧《绝密较量》央一开播,张鲁一高圆圆主演
  • 梅花画与咏梅诗
  • 大学2025丨专访北邮校长徐坤:工科教育要真正回归工程本质
  • 理想汽车副总裁刘杰:不要被竞争牵着鼻子走,也不迷信护城河