electron 基础项目搭建 &&主线程和渲染线程的通信

electron

一、初始化一个 electron 项目

1.先创建一个 package.json 文件

npm init -y

2.下载安装 electron

  • 注意要切换淘宝镜像下载
    npm instsll electron -S

3.在 package.json 下配置执行脚本

  • 先安装 nodemon
"scripts": {
    "start": "nodemon --exec electron . --watch ./ --ext .html,.js,.css"
  },

4.在根目录下创建 main.js 文件

const { app, BrowserWindow } = require("electron");

// 主进程
const createWindow = () => {
  const win = new BrowserWindow({
    // 窗口大小
    width: 1400,
    height: 800,
    // 最小的窗口大小
    minHeight: 300,
    minWidth: 400,
    // 窗口是否显示
    show: true,
    // 是否可以拖动
    movable: true,
    // 是否有顶部状态栏,拖动条
    // frame: false,
    // 导致隐藏的标题栏和完整大小的内容窗口
    // titleBarStyle: "default",
    // 窗口初始背景颜色
    backgroundColor: "aliceblue",
  });

  // 打开调试工具
  win.webContents.openDevTools();

  // 给窗口转载页面
  win.loadFile("./render/index.html");

  win.once("ready-to-show", () => {
    win.show();
  });
};

app.on("window-all-closed", () => {
  console.log("window-all-closed");

  // 对于 MACOS 系统,关闭窗口时,不会直接推出应用
  if (process.platform !== "darwin") {
    app.quit();
  }
});

app.whenReady().then(() => {
  createWindow();
  // 在 MacOS 下,当全部窗口关闭,点击 dock 图标,窗口再次打开。
  app.on("activate", () => {
    if (BrowserWindow.getAllWindows().length === 0) {
      createWindow();
    }
  });

  // console.log(app.isReady())
  // console.log(app.getPath('desktop'))
  // console.log(app.getPath('music'))
  // console.log(app.getPath('temp'))
  // console.log(app.getPath('userData'))

  // console.log(BrowserWindow.getAllWindows().length)
});

process.env["ELECTRON_DISABLE_SECURITY_WARNINGS"] = "true";

5.在根目录下创建文件夹 render 里面创建入口文件 index.html

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <!-- <meta http-equiv="Content-Security-Policy" content="script-src 'self' unsafe-eval"> -->
    <title>Document</title>
  </head>
  <body>
    <h1>第一个 electron 项目</h1>
  </body>
</html>

二、主进程和渲染进程通信

  • 目录结构
  --根目录
    --controller          封装的主线程收发数据
      --ipcMessage.js
    --preload         contextBridge 方法,主线程和渲染线程沟通的桥梁
      --index.js
    --render          加载的页面入口
      --app.js
      --index.html
      --style.css
      --vue.global.js   vue的项目包,本示例页面使用 vue3
    --main.js          项目入口

1.通信之前需要有 contextBridge 作为主线程和渲染现场之间沟通的桥梁

  • 使用 contextBridge 方法,将主线程的信息发送到渲染线程
// 例,将 electron 和 node 版本号发往渲染现线程
const { contextBridge } = require("electron");

// 发送 ,该信息的 key 为 myAPI
contextBridge.exposeInMainWorld("myAPI", {
  versions: process.versions,
});

// 页面中获取方法
const versions = window.myAPI.versions;
// 获取版本号
// chromeVersion: versions.chrome,
// NodeVersion: versions.node,
// electronVersion: versions.electron

2.渲染进程向主进程发送同步信息

  • 渲染进程使用方法 ipcRenderer.send('事件名','信息')发送消息,此操作在 contextBridge
  • 主线程使用方法 ipcMain 接收,使用方法 event.sender.send 返回内容
// --------------contextBridge------------------
// 创建方法 sendSync 发送消息
const sendSync = (message) => {
  ipcRenderer.send("sync-send-event", message);
};
// 讲方法抛出到 渲染线程调用
contextBridge.exposeInMainWorld("myAPI", {
  sendSync,
});
// -----------------渲染线程--------------------------
// 渲染线程调用
myAPI.sendSync("from renderer message 1");

// -----------------------主线程--------------------
// 主线程接受数据
// 同步事件监听
ipcMain.on("sync-send-event", (event, msg) => {
  // console.log(msg);
  // 使用参数 event 的方法 返回消息
  event.sender.send("sync-receive-event", "我已经收到:" + msg);
});
  • contextBridge 接收消息,并将方法抛出到渲染线程,渲染线程创建事件监听
// -----------------contextBridge-------------------
// 使用 ipcRenderer.on 创建时间同步监听
const recieveSyncMsg = () => {
  return new Promise((resolve) => {
    ipcRenderer.on("sync-receive-event", (event, msg) => {
      // console.log(msg)
      resolve(msg);
    });
  });
};
// 将事件 recieveSyncMsg 发送到渲染线程
contextBridge.exposeInMainWorld("myAPI", {
  recieveSyncMsg,
});

// --------------------渲染线程-------------------

// 使用async await 创建同步事件监听
async mounted(){
  const result = await myAPI.recieveSyncMsg();
}

以上是一套完整的渲染线程发送数据 -> 主线程接受数据并返回 -> 渲染线程接收返回数据 的过程

3.渲染进程向主进程发送异步消息

  • 渲染线程发送数据使用 ipcRenderer.invoke 方法,发送数据的方法在 contextBridge 中使用,同样将方法抛出到渲染线程的 js 文件调用
  • 主线程接受数据使用方法 ipcMain.handle
// --------------contextBridge-------------------
// 发送请求的方法 ipcRenderer.invoke 的第一个参数是本次请求的 key,第二个参数可有可无, 使用 return 给渲染线程返回数据
const sendAsync = async () => {
  const result = await ipcRenderer.invoke("my-invokable-ipc");
  return result;
};
// 讲方法 抛出到渲染线程的页面
contextBridge.exposeInMainWorld("myAPI", {
  sendAsync,
});
// ----------------渲染线程---------------------------
// 如果有桥接的方法(contextBridge),建议IPC通信,全部应用异步。
// 点击事件的方法
async sendAsyncMsg() {
  const result = await myAPI.sendAsync()
  console.log(result)
}
// --------------主线程就收数据和返回数据--------------------
// 异步事件监听
// 如果渲染线程有数据传来可以使用 args 接收
ipcMain.handle('my-invokable-ipc', async (event, ...args) => {
  const result = await somePromise()
  return result
})
// 写一个异步函数,模拟异步方法,三秒后返回数据
function somePromise() {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      resolve('message from main process.')
    }, 3000)
  })
}
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
引用\[1\]:在Electron中,线程是指运行应用程序的进程,它负责管理应用程序的生命周期、处理系统级别的操作和与操作系统进行交互。线程是一个Node.js进程,可以执行文件系统操作、网络请求等。在线程中,可以发送同步和异步消息,并通过不同的方式进行响应。比如,可以通过设置`global.eventValue.returnValue`来同步响应消息,或者通过`global.eventValue.reply`或`global.eventValue.sender.send`来异步响应消息。\[1\] 引用\[2\]:渲染线程是指在Electron中运行的Web页面的进程,它负责渲染和显示应用程序的用户界面。渲染线程是基于Chromium的多进程架构,每个Web页面都在独立的渲染进程中运行。在渲染线程中,可以通过`webContents.send`方法向线程发送消息。同时,渲染线程也可以通过监听`ipcMain`的事件来接收线程发送的消息。\[2\] 所以,线程是运行应用程序的进程,负责管理应用程序的生命周期和与操作系统的交互,而渲染线程是运行Web页面的进程,负责渲染和显示用户界面。 #### 引用[.reference_title] - *1* *2* [electron 线程渲染线程通信](https://blog.csdn.net/weixin_42551915/article/details/114687032)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [第一篇:electron 线程调试---vscode](https://blog.csdn.net/z1067832450_/article/details/121684008)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insert_down1,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值