Electron 主进程与渲染进程通信

主进程与渲染进程之间通信

main.js

const { app, BrowserWindow, Menu, ipcMain } = require('electron')

console.log(process.platform)

// 创建窗口
function createWindow () {
  console.log('ready')
  // 创建主进程
  const mainWin = new BrowserWindow({
    title: '自定义菜单',
    show: false, // true:显示窗体,false: 不显示窗体
    width: 800,
    height: 400,
    webPreferences: {
      nodeIntegration: true, // 允许浏览器环境使用Node API
      enableRemoteModule: true, // 允许页面使用 remote
    }
  })

  // 定义自己需要的菜单项
  const menuTemp = [
    {
      label: 'send',
      click() {
        BrowserWindow.getFocusedWindow().webContents.send('mtp', '来自于自进程的消息')
      }
    },
    {
      label: 'tool',
      click() {
        mainWin.webContents.openDevTools() // 打开调试面板
      }
    }
  ]

  // 生成菜单
  const menu = Menu.buildFromTemplate(menuTemp)

  // 将菜单添加到应用里
  Menu.setApplicationMenu(menu)

  // 在当前窗口中加载指定界面让它显示具体的内容
  mainWin.loadFile('index.html')
  

  mainWin.on('ready-to-show', () => {
    mainWin.show() // 在窗体完全加载完成后,显示窗体,避免白页现象
  })

  mainWin.on('close', () => {
    console.log('close')
    //mainWin = null
  })
}

// 当 app 启动之后,执行窗口创建等操作
app.on('ready', createWindow)

app.on('window-all-closed', () => {
  console.log('window-all-closed')
  app.quit()
})


// 主进程接收渲染进程传递的消息
ipcMain.on('msg1', (e, data) => {
  console.log(data)
  e.sender.send('msg1Re', 'msg1Re')
})

ipcMain.on('msg2', (e, data) => {
  console.log(data)
  e.returnValue = 'msg2Re'
})

index.js

const { ipcRenderer } = require('electron')

window.addEventListener('DOMContentLoaded', () => {
  const aBtn = document.getElementsByTagName('button')

  // 使用 异步API 在渲染进程中发送消息
  aBtn[0].addEventListener('click', () => {
    ipcRenderer.send('msg1', 'msg1')
  })

  // 使用 同步API 在渲染进程中发送消息
  aBtn[1].addEventListener('click', () => {
    const res = ipcRenderer.sendSync('msg2', 'msg2')
    console.log(res)
  })

 
  // 接收消息
  ipcRenderer.on('msg1Re', (e, data) => {
    console.log(data)
  })

  ipcRenderer.on('mtp', (e, data) => {
    console.log(data)
  })
})

渲染进程之间通信

渲染进程之间通信需要借助第三方完成数据中转

 

基于本地存储的渲染进程通信

index.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title></title>
</head>

<body>
  <h2>渲染进程间通信</h2>
  <button id="btn">打开窗口2</button>
  <script src="index.js"></script>
</body>
</html>

main.js

const { app, BrowserWindow, Menu, ipcMain } = require('electron')

console.log(process.platform)

// 定义全局变量存放主窗口 id
let mainWinId = null

// 创建窗口
function createWindow () {
  console.log('ready')
  // 创建主进程
  const mainWin = new BrowserWindow({
    title: '自定义菜单',
    show: false, // true:显示窗体,false: 不显示窗体
    width: 800,
    height: 400,
    webPreferences: {
      nodeIntegration: true, // 允许浏览器环境使用Node API
      enableRemoteModule: true, // 允许页面使用 remote
    }
  })

  // 在当前窗口中加载指定界面让它显示具体的内容
  mainWin.loadFile('index.html')
  
  mainWinId = mainWin.id

  mainWin.on('ready-to-show', () => {
    mainWin.show() // 在窗体完全加载完成后,显示窗体,避免白页现象
  })

  mainWin.on('close', () => {
    console.log('close')
    //mainWin = null
  })
}

// 当 app 启动之后,执行窗口创建等操作
app.on('ready', createWindow)

app.on('window-all-closed', () => {
  console.log('window-all-closed')
  app.quit()
})


// 主进程接收渲染进程传递的消息
ipcMain.on('openWin2', () => {
  // 创建窗口
  const subWin1 = new BrowserWindow({
    width: 400,
    height: 300,
    parent: BrowserWindow.fromId(mainWinId),
    webPreferences: {
      nodeIntegration: true, // 允许浏览器环境使用Node API
      enableRemoteModule: true, // 允许页面使用 remote
    },
  })

  subWin1.loadFile('subWin1.html')
})

index.js

const { ipcRenderer } = require('electron')

window.addEventListener('DOMContentLoaded', () => {
  const oBtn = document.getElementById('btn')

  oBtn.addEventListener('click', () => {
    ipcRenderer.send('openWin2')

    // 打开窗口后,存储数据在本地
    localStorage.setItem('name', 'name1')
  })
})

subWin1.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>窗口2</title>
</head>

<body>
  <h2>当前窗口2</h2>
  获取到index.html中的数据: <input type="text" id="txt">
  <script src="subWin1.js"></script>
</body>
</html>

subWin1.js

window.addEventListener('DOMContentLoaded', () => {
  const oInput = document.getElementById('txt')
  const val = localStorage.getItem('name')
  oInput.value = val
})

基于主进程的渲染进程通信

subWin1.html

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>窗口2</title>
</head>

<body>
  <h2>当前窗口2</h2>
  获取到index.html中的数据: <input type="text" id="txt">
  <br><br>
  <button id="btn">发送数据</button>
  <script src="subWin1.js"></script>
</body>
</html>

subWin1.js

const { ipcRenderer } = require('electron')

window.addEventListener('DOMContentLoaded', () => {
  // 发送数据给 index.js
  const oBtn = document.getElementById('btn')
  oBtn.addEventListener('click', () => {
    ipcRenderer.send('stm', 'stm')
  })

  // 接收数据
  ipcRenderer.on('its', (e, data) => {
    console.log(data)
  })
})

main.js

const { app, BrowserWindow, Menu, ipcMain } = require('electron')

console.log(process.platform)

// 定义全局变量存放主窗口 id
let mainWinId = null

// 创建窗口
function createWindow () {
  console.log('ready')
  // 创建主进程
  const mainWin = new BrowserWindow({
    title: '自定义菜单',
    show: false, // true:显示窗体,false: 不显示窗体
    width: 800,
    height: 400,
    webPreferences: {
      nodeIntegration: true, // 允许浏览器环境使用Node API
      enableRemoteModule: true, // 允许页面使用 remote
    }
  })

  // 定义自己需要的菜单项
  const menuTemp = [
    {
      label: 'send',
      click() {
        BrowserWindow.getFocusedWindow().webContents.send('mtp', '来自于自进程的消息')
      }
    },
    {
      label: 'tool',
      click() {
        mainWin.webContents.openDevTools() // 打开调试面板
      }
    }
  ]

  // 生成菜单
  const menu = Menu.buildFromTemplate(menuTemp)

  // 将菜单添加到应用里
  //Menu.setApplicationMenu(menu)

  // 在当前窗口中加载指定界面让它显示具体的内容
  mainWin.loadFile('index.html')
  
  mainWinId = mainWin.id

  mainWin.on('ready-to-show', () => {
    mainWin.show() // 在窗体完全加载完成后,显示窗体,避免白页现象
  })

  mainWin.on('close', () => {
    console.log('close')
    //mainWin = null
  })
}

// 当 app 启动之后,执行窗口创建等操作
app.on('ready', createWindow)

app.on('window-all-closed', () => {
  console.log('window-all-closed')
  app.quit()
})


// 主进程接收渲染进程传递的消息
ipcMain.on('openWin2', (e, data) => {
  // 创建窗口
  const subWin1 = new BrowserWindow({
    width: 400,
    height: 300,
    parent: BrowserWindow.fromId(mainWinId),
    webPreferences: {
      nodeIntegration: true, // 允许浏览器环境使用Node API
      enableRemoteModule: true, // 允许页面使用 remote
    },
  })

  subWin1.loadFile('subWin1.html')

  // 窗口加载完成后执行数据发送
  subWin1.webContents.on('did-finish-load', () => {
    subWin1.webContents.send('its', data)
  })
})

ipcMain.on('stm', (e, data) => {
  // 当前我们需要将 data 经过 main 进程转交给指定的渲染进程
  // 此时我们可以依据指定的窗口 ID 来获取对应的渲染进程,然后执行消息的发送
  const mainWin = BrowserWindow.fromId(mainWinId)
  mainWin.webContents.send('mti', data)
})

index.js

const { ipcRenderer } = require('electron')

window.addEventListener('DOMContentLoaded', () => {
  const oBtn = document.getElementById('btn')

  oBtn.addEventListener('click', () => {
    ipcRenderer.send('openWin2', 'from index.js')
  })

  // 接收消息
  ipcRenderer.on('mti', (e, data) => {
    console.log(data)
  })
})

1

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值