electron之进程间通信

Electron进程间通信

使用electron编写程序时经常遇到下面这种场景:

当用户点击一个按钮时,需要将页面输入的信息保存到本地电脑上;

或者是点击菜单时,需要页面窗口做出响应。

用户点击的按钮和窗口展示的内容是运行在渲染进程中,而保存的操作和点击菜单是运行在主进程中的,渲染进程和主进程无法直接通信,

这是就需要使用到进程间通信(IPC)

为了实现这种通信,Electron提供了 ipcMainipcRenderer 模块。

渲染进程到主进程的通信

下面是一个简单的例子,介绍在页面输入文本信息,然后点击按钮将文本信息保存到本地电脑,然后点击查询,读取本地电脑文件并将读取的文本展示出来。

main.js

javascript 复制代码
const { app, BrowserWindow, ipcMain } = require('electron')
const {join} = require("path");
const fs = require("fs");

// 应用创建窗口
const createWindow = () => {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: join(__dirname, 'preload.js')
        }
    })
    win.loadFile('index.html')
    win.webContents.openDevTools();
}
app.whenReady().then(() => {
    // 处理保存文本的事件
    ipcMain.handle('save-text', async (event, text) => {
        const filePath = `./output.txt`;
        fs.writeFileSync(filePath, text);
    });

    // 处理查询文本的事件
    ipcMain.handle('query-text', async (event) => {
        const filePath = `./output.txt`;
        return fs.readFileSync(filePath, {encoding: 'utf-8'});
    });
    createWindow()
})

preload.js

js 复制代码
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('myAPI', {
    saveText: (text) => ipcRenderer.invoke('save-text', text),
    queryText: () => ipcRenderer.invoke('query-text'),
})

index.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
  <label>
      输入文本信息:
      <input id="input-name" type="text">
  </label>
  <input id="save" type="button" value="保存">
  <div>
      <input id="query" type="button" value="读取文本信息">
      <div id="text"></div>
  </div>

<script>
    const saveButton = document.getElementById('save')
    saveButton.addEventListener('click', () => {
        const inputName = document.getElementById('input-name')
        window.myAPI.saveText(inputName.value)
    })

    const queryButton = document.getElementById('query')
    queryButton.addEventListener('click', async () => {
        const text = document.getElementById('text')
        text.innerHTML = await window.myAPI.queryText()
    })

</script>
</body>
</html>

运行结果如下:

输入hello world!,点击保存,然后点击读取按钮,就会把保存的文件内容展示出来。

这个是渲染进程到主进程的通信,下面介绍一下主进程到渲染进程的通信。

主进程到渲染进程的通信

我们在窗口添加一个设置菜单和两个子菜单+1,-1,

点击子菜单时页面数字做出相应反馈。

main.js

js 复制代码
const { app, BrowserWindow, Menu } = require('electron')
const {join} = require("path");

// 应用创建窗口
const createWindow = () => {
    const win = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
            preload: join(__dirname, 'preload.js')
        }
    })
    // 设置窗口菜单
    const menu = Menu.buildFromTemplate([
        {
            label: '设置',
            submenu: [
                {
                    // 点击+1按钮时触发update-counter事件并传递参数1
                    click: () => win.webContents.send('update-counter', 1),
                    label: '+1'
                },
                {
                    // 点击-1按钮时触发update-counter事件并传递参数-1
                    click: () => win.webContents.send('update-counter', -1),
                    label: '-1'
                }
            ]
        }
    ])

    Menu.setApplicationMenu(menu)
    win.loadFile('index.html')
    win.webContents.openDevTools();
}
app.whenReady().then(() => {
    createWindow()
})

preload.js

js 复制代码
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('myAPI', {
    // 渲染进程监听update-counter事件
    handleCounter: (callback) => ipcRenderer.on('update-counter', callback)
})

index.html

html 复制代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
  <div>count:<span id="count">0</span></div>

<script>
    const count = document.getElementById('count')
    // 传入监听update-counter事件的回调函数
    window.myAPI.handleCounter((event, value) => {
        const num = Number(count.innerText)
        count.innerText = num + value
    })

</script>
</body>
</html>

运行结果如下

以上就是electron的进程间通信,欢迎大家在评论区留言指正,相互学习

相关推荐
子兮曰1 天前
jev-ultrafast 深度解析:7 秒订机票的浏览器 Agent 是如何炼成的
前端·后端·agent
子兮曰1 天前
Jev 爆发一周:7 秒 Agent 背后的 System One 生态与三场争议
前端·后端·ai编程
前端小万1 天前
写公众号赚了 3000 块后,我做了一款叫 "一键成稿" 的软件
前端·微信小程序
爱勇宝1 天前
ZCode 开源 24 小时:一份没有历史的账本,回答不了"有没有偷代码"
前端·后端·chatglm (智谱)
三十而立洋1 天前
Cookie 详解:从产生到安全,一次讲透
前端·javascript
大蓝头1 天前
安装包UI美化之路-nsNiuniuSkin全新UI调试与预览方法
ui·electron·安装包·截图控件·截屏控件
卡布鲁1 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
李少兄1 天前
JavaScript 隐式全局变量解析
javascript
汉堡大王95271 天前
Jev:不是聊天机器人, 而是一个智能 if 语句
前端·人工智能·后端
梦想很大很大1 天前
从运行事实到回归证据:Workrun 的 Telemetry 与 Evaluation 实践
前端·人工智能·后端