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

electron + vue3 + vite 主进程到渲染进程的单向通信

用示例讲解下主进程到渲染进程的单向通信
初始版本项目结构可参考项目:https://github.com/ylpxzx/electron-forge-project/tree/init_project

请添加图片描述

主进程到渲染进程(单向)

以Electron官方文档给出的”主进程主动触发动作,发送内容给渲染进程“为例。
实现整项目示例:https://github.com/ylpxzx/electron-forge-project/tree/main_to_render

mainWindow.webContents.send(消息名, 消息内容)

  • mainWindow是一个 BrowserWindow 实例,表示应用程序的主窗口
  • webContents是 mainWindow 的一个属性,允许你访问和控制窗口中的网页内容
  • send 方法用于从主进程向渲染进程发送异步消息

通信逻辑

  • src/main.js
    通过点击菜单栏的按钮,模拟主进程向渲染进程发送消息
    请添加图片描述具体来说,这段代码的作用是:从主进程向渲染进程发送一个名为 ‘update-counter’ 的消息。该消息携带一个参数值 1。在渲染进程中,你可以通过监听 ‘update-counter’ 事件来接收这个消息并进行相应的处理

    完整代码如下:

    import { app, BrowserWindow, Menu } from 'electron';
    import path from 'node:path';
    import started from 'electron-squirrel-startup';
    
    // Avoid Warning:Electron Security Warning (Insecure Content-Security-Policy) This renderer process has either no Content Security
    process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = "true";
    
    if (started) {
      app.quit();
    }
    
    const createWindow = () => {
      const mainWindow = new BrowserWindow({
        width: 800,
        height: 600,
        webPreferences: {
          preload: path.join(__dirname, 'preload.js'),
        },
      });
    
      const menu = Menu.buildFromTemplate([
        {
          label: 'Menu',
          submenu: [
            {
              click: () => mainWindow.webContents.send('update-counter', 1),
              label: 'Increment'
            },
            {
              click: () => mainWindow.webContents.send('update-counter', -1),
              label: 'Decrement'
            }
          ]
        }
      ])
    
      Menu.setApplicationMenu(menu)
    
      if (MAIN_WINDOW_VITE_DEV_SERVER_URL) {
        mainWindow.loadURL(MAIN_WINDOW_VITE_DEV_SERVER_URL);
      } else {
        mainWindow.loadFile(path.join(__dirname, `../renderer/${MAIN_WINDOW_VITE_NAME}/index.html`));
      }
    
      mainWindow.webContents.openDevTools();
    };
    
    app.whenReady().then(() => {
      createWindow();
    
      app.on('activate', () => {
        if (BrowserWindow.getAllWindows().length === 0) {
          createWindow();
        }
      });
    });
    
    app.on('window-all-closed', () => {
      if (process.platform !== 'darwin') {
        app.quit();
      }
    });
    

    在这个示例中,当用户点击窗口菜单的Increment 时向渲染进程发送1,点击窗口菜单的Decrement时向渲染进程发送-1

  • src/preload.js

    preload.js 用于上下文隔离;将确保您的 预加载脚本Electron的内部逻辑 运行在所加载的webcontent网页之外的另一个独立的上下文环境里。 有助于阻止网站访问Electron 的内部组件和 预加载脚本可访问的高等级权限的API。简而言之就是提供一个入口给渲染进程(前端页面)使用,避免被攻击者随意调用electron内部API。

    该段代码的作用是向外暴露一个监听函数onUpdateCounter , 前端页面调用该方法进行监听。

    const { contextBridge, ipcRenderer } = require('electron/renderer')
    
    contextBridge.exposeInMainWorld('electronAPI', {
      onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value)),
    })
    

页面示例

通信逻辑实现后,接下来就用一个页面来验证结果

  • src/vue-project/pages/mainToRenderTo/TwoWay.vue

    <template>
      <div>
        <div>click menu to set counter</div>
        Current value: <strong id="counter">{{ inputVal }}</strong>
      </div>
    </template>
    
    <script setup>
    import { ref } from 'vue'
    const inputVal = ref(0)
    electronAPI.onUpdateCounter((value) => {
      inputVal.value = inputVal.value + value
    })
    </script>
    
  • src/vue-project/router/index.js

    import { createWebHashHistory, createRouter } from 'vue-router'
    
    import HomeView from '@/vue-project/pages/home/index.vue'
    import MainToRender from '@/vue-project/pages/mainToRender/index.vue'
    
    const routes = [
      { path: '/', component: HomeView },
      // 注册示例页面路由
      { path: '/mainToRender', component: MainToRender },
    ]
    const router = createRouter({
      history: createWebHashHistory(),
      routes,
    })
    
    export default router;
    
  • src/vue-project/App.vue

    <template>
      <h1>🖥️ Hello World!</h1>
      <p>Welcome to your Electron application.</p>
      <p>
        <strong>Current route path:</strong> {{ $route.fullPath }}
      </p>
      <nav>
        <div>
          <RouterLink to="/">Go to Home</RouterLink>
        </div>
        <div>
          <RouterLink to="/mainToRender">Main-Process --> Render-Process</RouterLink>
        </div>
      </nav>
      <div style="margin-top: 20px; border: 1px solid grey; padding: 20px; border-radius: 10px;">
        <router-view></router-view>
      </div>
    </template>
    
    <script setup>
    </script>
    

项目结构

请添加图片描述


http://www.kler.cn/a/578554.html

相关文章:

  • MyBatis Mapper 接口的作用,以及如何将 Mapper 接口与 SQL 映射文件关联起来
  • 祝福语【算法赛】
  • Conda常用命令汇总
  • 2020CVPR速读:SiamBAN,用于视觉跟踪的Siamese框自适应网络
  • Ubuntu工控卫士在制造企业中的应用案例
  • Python深度学习算法介绍
  • 聊一聊 Android 的消息机制
  • Aws batch task 无法拉取ECR 镜像unable to pull secrets or registry auth 问题排查
  • 开源项目介绍:Native-LLM-for-Android
  • 大模型量化技术原理总结 [吃果冻不吐果冻皮]
  • 设计模式 - 工厂模式 精准梳理精准记忆
  • E2-13.找单词(dfs)
  • 分布式ID生成方案:数据库号段、Redis与第三方开源实现
  • 10个实用IntelliJ IDEA插件
  • Linux(Centos 7.6)命令详解:vi
  • Apache SeaTunnel 人物专访 | 张东浩:从使用者到Committer的开源历程
  • 力扣刷题167. 两数之和 II - 输入有序数组
  • 极验三代推理验证码逆向分析
  • 11套!量产15W~1000W开关电源电路全套方案资料合集!
  • 什么是hive