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
相关推荐
Genevieve_xiao4 分钟前
【数据结构与算法】【xjtuse】面向考纲学习(下)
java·数据结构·学习·算法
mpHH20 分钟前
ivorysql 源码分析-双port兼容
数据库·学习·postgresql
北杳同学28 分钟前
前端一些用得上的有意思网站
前端·javascript·vue.js·学习
小帅学编程44 分钟前
JVM学习记录
jvm·学习
xian_wwq44 分钟前
【学习笔记】威胁情报
网络·笔记·学习
小糊涂加油1 小时前
TypeScript学习笔记
笔记·学习
@游子1 小时前
Python学习笔记-Day6
笔记·python·学习
xunyan62341 小时前
面向对象(下)-模版方法的设计模式其应用场景
java·学习·设计模式
四维碎片1 小时前
【Qt】QTimer 学习笔记总结
笔记·qt·学习
组合缺一1 小时前
Solon AI 开发学习16 - generate - 生成模型(图、音、视)
java·人工智能·学习·ai·llm·solon