Electron学习(三):进程间通信

Electron学习(三):进程间通信

1、进程间通信 (IPC) 是在 Electron 中构建功能丰富的桌面应用程序的关键部分之一。

2、由于主进程和渲染器进程在 Electron 的进程模型具有不同的职责,因此 IPC 是执行许多常见任务的唯一方法。

一、预加载脚本

在src目录下新建preload.js文件

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

if (contextBridge && ipcRenderer) {
    try {
        contextBridge.exposeInMainWorld('electronAPI', {
            // 注意:这里需要接收参数并传递给主进程
            setNumber: (num1, num2) => ipcRenderer.invoke('sumNumbers', num1, num2),
        });
    } catch (error) {
        console.error('Failed to expose electronAPI:', error);
    }
} else {
    console.error('contextBridge or ipcRenderer is undefined');
}

处理渲染进程发送的同步消息请求,将其添加到background.js中

js 复制代码
ipcMain.handle('sumNumbers', async (event, num1, num2) => {
  return num1 + num2;
});

二、调整background.js

将预加载脚本添加到background.js中

js 复制代码
'use strict'

import { app, protocol, BrowserWindow, ipcMain, Menu } from 'electron'
import { createProtocol } from 'vue-cli-plugin-electron-builder/lib'
import { resolve } from 'path'
const isDevelopment = process.env.NODE_ENV !== 'production'

protocol.registerSchemesAsPrivileged([
  { scheme: 'app', privileges: { secure: true, standard: true } }
])

async function createWindow() {
  let preloadPath;
  if (process.env.NODE_ENV === 'development') {
    // 开发环境:基于项目根目录拼接
    preloadPath = resolve(process.cwd(), 'src/preload.js');
  } else {
    // 生产环境:基于主进程打包目录拼接(根据实际打包路径调整)
    preloadPath = resolve(__dirname, '../preload/preload.js');
  }
  
  // 关闭已有窗口(防止热重载时多窗口)
  BrowserWindow.getAllWindows().forEach(win => win.destroy());
  
  const win = new BrowserWindow({
    width: 1200,
    height: 800,
    minWidth: 1200,
    minHeight: 800,
    webPreferences: {
      preload: preloadPath
    }
  })

  if (process.env.WEBPACK_DEV_SERVER_URL) {
    await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
  } else {
    createProtocol('app')
    win.loadURL('app://./index.html')
  }
}

// 隐藏客户端默认菜单
Menu.setApplicationMenu(null)

// 窗口被全部关闭
app.on('window-all-closed', () => {
  if (process.platform !== 'darwin') {
    app.quit()
  }
})

// 应用被激活时
app.on('activate', () => {
  if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

// 应用准备就绪时
app.on('ready', async () => {
  await createWindow();
})

// 判断是否为开发环境
if (isDevelopment) {
  if (process.platform === 'win32') {
    process.on('message', (data) => {
      if (data === 'graceful-exit') {
        app.quit()
      }
    })
  } else {
    process.on('SIGTERM', () => {
      app.quit()
    })
  }
}

// 处理传递过来的信息
ipcMain.handle('sumNumbers', async (event, num1, num2) => {
  return num1 + num2;
});

三、在实际页面中使用

在HelloWord.vue页面中使用 IPC 通信

html 复制代码
<template>
  <div class="hello">
    <h1>{{ msg }}</h1>
    <p>从预加载获取的数据:{{ total }}</p>
  </div>
</template>

<script>
export default {
  name: 'HelloWorld',
  props: {
    msg: String
  },
  data() {
    return {
      total: 0,
    }
  },
  mounted() {
    this.getNumber();
  },
  methods: {
    async getNumber() {
      let total = await window.electronAPI.setNumber(1, 2);
      console.log('total', total);
      this.total = total;
    }
  }
}
</script>
<style scoped>
h3 {
  margin: 40px 0 0;
}

ul {
  list-style-type: none;
  padding: 0;
}

li {
  display: inline-block;
  margin: 0 10px;
}

a {
  color: #42b983;
}
</style>

四、调整vue.config.js

js 复制代码
module.exports = {
    transpileDependencies: [],
    lintOnSave: false,
    publicPath: "./",
    outputDir: "dist",
    assetsDir: "static",
    productionSourceMap: false,
    configureWebpack(config) {
        config.devtool = false;
    },
    pluginOptions: {
        electronBuilder: {
            nodeIntegration: false,
            contextIsolation: true,
            mainProcessFile: 'src/background.js',
            chainWebpackMainProcess: (config) => {
                config.output.filename((file) => {
                    if (file.chunk.name === "index") {
                        return "background.js";
                    } else {
                        return "[name].js";
                    }
                });
            },
            // 预加载脚本
            preload: 'src/preload.js',
        }
    }
}

五、运行项目查看结果

shell 复制代码
npm run electron:serve
相关推荐
一拳不是超人1 天前
Electron主窗口弹框被WebContentView遮挡?独立WebContentView弹框方案详解!
前端·javascript·electron
西岸行者5 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意5 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
柯南95275 天前
Electron 无边框窗口拖拽实现
vue.js·electron
卸任5 天前
Windows判断是笔记本还是台式
前端·react.js·electron
别催小唐敲代码5 天前
嵌入式学习路线
学习
毛小茛5 天前
计算机系统概论——校验码
学习
babe小鑫5 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms5 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下5 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs