Electron——流程模型、进程通信

electron

  • 应用广泛的桌面应用开发框架
  • 本质结合了chromium和node.js
    在这里插入图片描述

Electron流程模型

主进程

仅一个,主进程在 Node.js 环境中运行,具有 require 模块和使用所有 Node.js API 的能力

窗口管理

使用 BrowserWindow 模块创建和管理应用程序窗口

渲染器进程

每个打开的BrowserWindow 生成单独的渲染器进程(代码是须遵照网页标准的 )即:渲染器无权直接访问 require 或其他 Node.js API

Preload 脚本

包含了那些执行于渲染器进程中,且先于网页内容开始加载的代码,
在打开窗口时通过webPreferences 附加到主进程

const { BrowserWindow } = require('electron')
// ...
const win = new BrowserWindow({
  webPreferences: {
    preload: 'path/to/preload.js'
  }
})

预加载脚本与浏览器共享同一个全局 Window 接口,所以它通过在全局 window 中暴露任意 API 来增强渲染器,
electron12之后默认开启上下文隔离,所以不能直接window.myApi=function(){},采用以下的方式:
实现:

const { contextBridge } = require('electron')

contextBridge.exposeInMainWorld('myAPI', {
  desktop: true
})

在render.js中:

console.log(window.myAPI)// => { desktop: true }

预加载脚本访问的window并不是网站能访问的对象
例如:

// ❌ 错误使用,它直接暴露了一个没有任何参数过滤的高等级权限 API
contextBridge.exposeInMainWorld('myAPI', {
  send: ipcRenderer.send
})

// ✅ 正确使用  暴露进程间通信相关 API 的正确方法是为每一种通信消息提供一种实现方法
contextBridge.exposeInMainWorld('myAPI', {
  loadPreferences: () => ipcRenderer.invoke('load-prefs')
})

正确:

在这里插入图片描述
别人的笔记:
笔记

窗口配置项:配置项

内容安全策略:CSPelectron-security

进程间的通信

官网地址:链接

IPC通道

  • ipcMain 是一个仅在主进程中以异步方式工作的模块,用于与渲染进程交换消息。
  • ipcRenderer 是一个仅在渲染进程中以异步方式工作的模块,用于与主进程交换消息。

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

  1. 主进程main.js
const { app, BrowserWindow, ipcMain } = require('electron/main')

const mainWindow = new BrowserWindow({
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })
//写在loadFile之前
  ipcMain.on('set-title', (event, title) => {
    const webContents = event.sender
    const win = BrowserWindow.fromWebContents(webContents)
    win.setTitle(title)
  })

  mainWindow.loadFile('index.html')
  1. preload.js暴露send方法给rendeder
    向渲染器进程暴露一个全局的 window.electronAPI 变量
    渲染器进程中使用 window.electronAPI.setTitle() 函数
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
  setTitle: (title) => ipcRenderer.send('set-title', title)
})
  1. renderer.js使用方法
setButton.addEventListener('click', () => {
  const title = titleInput.value
  window.electronAPI.setTitle(title)
})

渲染器进程到主进程(双向)

ipcRenderer.invokeipcMain.handle 搭配

  1. main.js ipcMain.handle
    主进程通过ipcMain.handle 来接收消息
//返回值将作为一个 Promise 返回到最初的 invoke 调用
  ipcMain.handle('dialog:openFile', handleFileOpen)
  //dialog: 前缀对代码没有影响。 它仅用作命名空间以帮助提高代码的可读性。
  1. preload.js
    渲染进程通过 ipcRenderer.invoke 发送消息
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
  openFile: () => ipcRenderer.invoke('dialog:openFile')
})
  1. renderer
  const filePath = await window.electronAPI.openFile()

主进程到渲染器进程

将消息从主进程发送到渲染器进程时,需要指定是哪一个渲染器接收消息
使用WebContents

  1. main.js
    通过mainWindow.webContents.send发送消息和参数
const mainWindow = new BrowserWindow({
    webPreferences: {
      preload: path.join(__dirname, 'preload.js')
    }
  })

const menu = Menu.buildFromTemplate([
    {
      label: app.name,
      submenu: [
        {
          click: () => mainWindow.webContents.send('update-counter', 1),
          label: 'Increment'
        },
        {
          click: () => mainWindow.webContents.send('update-counter', -1),
          label: 'Decrement'
        }
      ]
    }
  ])

  1. preload.js
    ipcRenderer.on接收
const { contextBridge, ipcRenderer } = require('electron')

contextBridge.exposeInMainWorld('electronAPI', {
  onUpdateCounter: (callback) => ipcRenderer.on('update-counter', (_event, value) => callback(value))
})
  1. renderer.js
window.electronAPI.onUpdateCounter(()=>{})

webview

electron与webview的通信

在窗口中webview引入其他网页,以节省开发成本,会再注入一些js、css来对这个页面进行改动,其中就有添加事件,webview所在窗口需要得知事件触发。

<template>
    <div class ="container">
        <webview
            id="webview"
            ref="webview"
            :src="webviewSrc"
            disablewebsecurity
            class="webview"
            nodeintegration
        />
    </div>
</template>

webview页面使用ipcRenderer向窗口发送信息
ipcRenderer.sendToHost()

  let ipcRenderer = require('electron').ipcRenderer
    var paramsJSON = {}
    ipcRenderer && ipcRenderer.sendToHost(paramsJSON)

webview所在页面监听接收信息

webview.addEventListener('ipc-message', (event) => {
    if (event.channel) {
        let params = JSON.parse(event.channel)
    }
})
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值