Electron學習筆記(一)

文章目錄

      • 相關筆記
      • 筆記說明
    • 一、輕松入門
      • 1、搭建開發環境
      • 2、創建窗口界面
      • 3、調試主進程
    • 二、主進程和渲染進程
      • 1、進程互訪
      • 2、渲染進程訪問主進程類型
      • 3、渲染進程訪問主進程自定義內容
      • 4、渲染進程向主進程發送消息
      • 5、主進程向渲染進程發送消息
      • 6、多個窗口的渲染進程接收主進程發送的消息
      • 7、渲染進程之間消息傳遞
        • 方法一:利用主進程進行中轉
        • 方法二:單向傳遞

相關筆記

  • Electron學習筆記(一)
  • Electron學習筆記(二)
  • Electron學習筆記(三)
  • Electron學習筆記(四)
  • Electron學習筆記(五)
  • Electron學習筆記(六)
  • 使用 electron-vite-vue 構建 electron + vue3 項目并打包

筆記說明

文本為學習《Electron 實戰 入門、進階與性能優化 劉曉倫 著》時所記錄的筆記 主要將書本上的案例運行一遍,針對原理部分并無相關記錄。筆記記錄于 2023年9月。

一、輕松入門

1、搭建開發環境

安裝 yarn :

npm i -g yarn

創建一個文件夾,進行項目的初始化:

yarn init -y

配置 Electron 的鏡像網站:

yarn config set electron_mirror https://registry.npmmirror.com/-/binary/electron/

使用 yarn 安裝 Electron:

yarn add electron --dev

2、創建窗口界面

創建一個 index.html 文件,內容如下:

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

新建一個 index.js 文件,內容如下:

const {app,BrowserWindow} = require('electron');let win = null;app.on('ready', function() {win = new BrowserWindow({// 為頁面集成Node.js環境webPreferences: {nodeIntegration: true}});// 訪問資源文件win.loadFile('index.html');// 程序啟動后開啟 開發者工具// win.webContents.openDevTools();win.on('close',function() {win = null;})
});app.on('window-all-closed',function() {app.quit();
})

更新 package.json 文件:

"scripts": {
"start": "electron ./index.js"
},

啟動項目:

yarn start

結果展示:

效果展示

3、調試主進程

點擊調試按鈕,創建 launch.json 文件 -> 選擇Node.js環境

調試

修改 launch.json 文件如下:

{"version": "0.2.0","configurations": [{"name": "調試主進程",// type: 調試環境為 Node.js 環境"type": "node","request": "launch","cwd": "${workspaceRoot}",// runtimeExecutable: 指向的是批處理文件,該批處理文件用于啟動 Electron// ${workspaceRoot} 是正在進行調試的程序的工作目錄的絕對路徑"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron","windows": {"runtimeExecutable": "${workspaceRoot}/node_modules/.bin/electron.cmd"},// 此處的參數是主進程程序路徑的簡寫形式,填寫 "./index.js" 亦可"args": ["."],"outputCapture": "std"}]
}

快捷鍵:

Ctrl+Shift+I:打開渲染進程的調試窗口

Ctrl+R:代碼修改后,刷新界面

二、主進程和渲染進程

1、進程互訪

注:原書籍中的代碼由于 Electron 版本的更新,remote 模塊無法直接導入使用,需要進行下載:

下載 remote 模塊:

yarn add @electron/remote

更新 index.js 文件如下:(主進程代碼

const {app,BrowserWindow} = require('electron');app.on('ready', function() {win = new BrowserWindow({// 為頁面集成Node.js環境webPreferences: {nodeIntegration: true,contextIsolation: false}});require("@electron/remote/main").initialize();require("@electron/remote/main").enable(win.webContents);// 訪問資源文件win.loadFile('index.html');// 程序啟動后開啟 開發者工具// win.webContents.openDevTools();win.on('close',function() {win = null;})
});app.on('window-all-closed',function() {app.quit();
})

參考鏈接:https://blog.csdn.net/m0_45961428/article/details/122982510

在 index.html 添加以下代碼:

<button id="openDevToolsBtn">打開開發者工具</button>
<script>const remote =require('@electron/remote');document.querySelector('#openDevToolsBtn').addEventListener('click',function() {remote.getCurrentWindow().webContents.openDevTools();})
</script>

運行程序:

yarn start

運行結果:(點擊按鈕可打開開發者工具)

運行結果

2、渲染進程訪問主進程類型

主進程代碼:主進程代碼

更新 index.html 文件如下:

<button id="makeNewWindow">創建新窗口</button>
<script>const remote = require('@electron/remote');// 在渲染進程中創建一個新的窗口document.querySelector('#makeNewWindow').addEventListener('click',function() {win = new remote.BrowserWindow({webPreferences: {nodeIntegration: true,}});win.loadFile('newWin.html');});
</script>

說明:創建 BrowserWindow 的過程依然在主進程中進行,是由 remote 模塊通知主進程完成相應的操作的,主進程創建了 BrowserWindow 對象的實例后,把對象的實例以遠程對象的形式返回給渲染進程。

3、渲染進程訪問主進程自定義內容

主進程代碼:主進程代碼

新建文件 mainModel.js:

let {BrowserWindow} = require('electron');exports.makeWin = function() {let win = new BrowserWindow({webPreferences: {nodeIntegration: true,}});return win;
}

更新 index.html 文件如下:

<button id="makeNewWindow2">創建新窗口2</button>
<script>const remote = require('@electron/remote');const mainModel = remote.require('./mainModel');let win2 = null;document.querySelector('#makeNewWindow2').addEventListener('click',function() {win2 = mainModel.makeWin();win2.loadFile('newWin.html');});
</script>

4、渲染進程向主進程發送消息

更新 index.html 文件:

<button id="sendMsg">向主進程發送消息</button>
<script>const {ipcRenderer} = require('electron');document.querySelector('#makeNewWindow2').addEventListener('click',() => {// msg:消息管道的名稱ipcRenderer.send('msg',{name: 'xiaom'},{name: 'xiaoh'});});
</script>

index.js 文件添加以下內容:(其余主進程代碼見:主進程代碼)

const {ipcMain} = require('electron');ipcMain.on('msg',(event,param1,param2) => {console.log(param1);console.log(param2);console.log(event.sender);
})

運行結果:

運行結果

5、主進程向渲染進程發送消息

在主進程 index.js 文件中添加以下代碼:

const {app,BrowserWindow} = require('electron');
const {ipcMain} = require('electron');let win = null;app.on('ready', function() {win = new BrowserWindow({// 為頁面集成Node.js環境webPreferences: {nodeIntegration: true,contextIsolation: false}});// 監聽渲染進程發來的消息,隨后再次發回給渲染進程ipcMain.on('msg',(event,param1,param2) => {win.webContents.send('msg_main',param1,param2);})// 訪問資源文件win.loadFile('index.html');win.on('close',function() {win = null;})
});

更新渲染進程 index.html 文件如下:

<button id="sendMsg">向主進程發送消息</button>
<script>const {ipcRenderer} = require('electron');// 接收 主進程發送的消息ipcRenderer.on('msg_main',(event,param1,param2) => {console.log(param1);console.log(param2);console.log(event.sender);})document.querySelector('#sendMsg').addEventListener('click',() => {ipcRenderer.send('msg',{name: 'xiaom'},{name: 'xiaoh'});});
</script>

運行程序后 -> 點擊按鈕(向主進程發送消息) -> Electron 程序控制臺將會打印主進程發送來的消息。

運行結果:

運行結果

6、多個窗口的渲染進程接收主進程發送的消息

更新主進程 index.js 文件:

const {app,BrowserWindow} = require('electron');
const {ipcMain} = require('electron');// 接收 渲染進程 發送來的消息 在VSCode控制臺打印消息
ipcMain.on('msg',(event,param1,param2) => {console.log(param1);console.log(param2);console.log(event.sender);
});let win = null;app.on('ready', function() {win = new BrowserWindow({// 為頁面集成Node.js環境webPreferences: {nodeIntegration: true,contextIsolation: false}});// 為了使 remote 模塊能夠使用需要執行以下操作require("@electron/remote/main").initialize();require("@electron/remote/main").enable(win.webContents);// 監聽 渲染進程 發來的消息,隨后再次發回給渲染進程ipcMain.on('msg',(event,param1,param2) => {// 單個窗口時使用:// win.webContents.send('msg_main',param1,param2);// 多個窗口時使用// 方法一:// event.sender.send('msg_main',param1,param2);// 方法二:event.reply('msg_main',param1,param2);})// 訪問資源文件win.loadFile('index.html');win.on('close',function() {win = null;})
});app.on('window-all-closed',function() {app.quit();
});

更新 index.html 文件如下:

<button id="makeNewWindow">創建新窗口</button>
<button id="sendMsg">向主進程發送消息</button>
<script>const remote = require('@electron/remote');const { ipcRenderer } = require('electron');// 在渲染進程中創建一個新的窗口document.querySelector('#makeNewWindow').addEventListener('click', function () {win = new remote.BrowserWindow({webPreferences: {nodeIntegration: true,contextIsolation: false}});win.loadFile('newWin.html');});// 監聽主進程發送來的消息ipcRenderer.on('msg_main', (event, param1, param2) => {console.log(param1);console.log(param2);console.log(event.sender);})// 點擊發送按鈕 發送消息至主進程document.querySelector('#sendMsg').addEventListener('click', () => {ipcRenderer.send('msg', { name: 'xiaom' }, { name: 'xiaoh' });});
</script>

newWin.html 文件內容如下:

<h1>newWindow</h1>
<button id="sendMsg2">向主進程發送消息</button>
<script>const { ipcRenderer } = require('electron');// 監聽主進程發送來的消息ipcRenderer.on('msg_main', (event, param1, param2) => {console.log(param1);console.log(param2);console.log(event.sender);})// 點擊發送按鈕 發送消息至主進程document.querySelector('#sendMsg2').addEventListener('click', () => {ipcRenderer.send('msg', { name: 'xiaod' }, { name: 'xiaoc' });});
</script>

7、渲染進程之間消息傳遞

一個程序有多個窗口,并要在窗口之間傳遞消息,可以通過主進程中轉,此處通過win1先將消息發送給主進程,主進程再將消息發送給win2。

方法一:利用主進程進行中轉

窗口(win1) --> 主進程(中轉) --> 窗口(win2)

窗口(win2) --> 主進程(中轉) --> 窗口(win1)

主進程 index.js 文件內容如下:

const {app,BrowserWindow} = require('electron');
const {ipcMain} = require('electron');let win = null;app.on('ready', function() {win = new BrowserWindow({// 為頁面集成Node.js環境webPreferences: {nodeIntegration: true,contextIsolation: false}});require("@electron/remote/main").initialize();require("@electron/remote/main").enable(win.webContents);// 監聽 窗口win1 (index.html) 發來的消息ipcMain.on('msg_1',(event,param1,param2) => {// 向 窗口win1 (index.html) 發送消息win.webContents.send('msg_main',param1,param2);});// 訪問資源文件win.loadFile('index.html');// 程序啟動后開啟 開發者工具win.webContents.openDevTools();win.on('close',function() {win = null;})
});app.on('window-all-closed',function() {app.quit();
})

窗口(win1) index.html 文件內容如下:

<h1>win1</h1>
<button id="makeNewWindow">創建新窗口win2</button>
<button id="sendMsg">向主進程發送消息</button>
<script>const remote = require('@electron/remote');const { ipcRenderer } = require('electron');// 在渲染進程中創建一個新的窗口(win2)document.querySelector('#makeNewWindow').addEventListener('click', function () {win2 = new remote.BrowserWindow({webPreferences: {nodeIntegration: true,contextIsolation: false}});win2.loadFile('win2.html');win2.webContents.openDevTools();// 接收 主進程 的消息后 向 win2 發送消息ipcRenderer.on('msg_main', (event, param1, param2) => {win2.webContents.send('msg_win2',param1,param2);});});// 接收 主進程 發送的消息ipcRenderer.on('msg_main', (event, param1, param2) => {console.log(param1);console.log(param2);console.log(event.sender);})// 點擊按鈕向 主進程 發送消息document.querySelector('#sendMsg').addEventListener('click', () => {ipcRenderer.send('msg_1', { name: 'xiaom' }, { name: 'xiaoh' });});
</script>

窗口(win2) win2.html 文件內容如下:

<h1>win2</h1>
<button id="sendMsg2">向主進程發送消息</button>
<script>const { ipcRenderer } = require('electron');// 接收 窗口 win1 (index.html) 發送來的消息ipcRenderer.on('msg_win2', (event, param1, param2) => {console.log(param1);console.log(param2);console.log(event.sender);})// 點擊按鈕向 主進程 發送消息document.querySelector('#sendMsg2').addEventListener('click', () => {ipcRenderer.send('msg_1', { name: 'xiaod' }, { name: 'xiaoc' });});
</script>

結果展示:

結果展示

方法二:單向傳遞

窗口(win1) --> 窗口(win2)

主進程 index.js 文件內容如下:(此方法無需主進程中轉,所以主進程無需接收消息)

const {app,BrowserWindow} = require('electron');let win = null;app.on('ready', function() {win = new BrowserWindow({// 為頁面集成Node.js環境webPreferences: {nodeIntegration: true,contextIsolation: false}});require("@electron/remote/main").initialize();require("@electron/remote/main").enable(win.webContents);// 訪問資源文件win.loadFile('index.html');// 程序啟動后開啟 開發者工具win.webContents.openDevTools();win.on('close',function() {win = null;})
});app.on('window-all-closed',function() {app.quit();
});

窗口(win1) index.html 文件內容如下:

<h1>win1</h1>
<button id="makeNewWindow">創建新窗口win2</button>
<button id="sendMsg">向窗口win2發送消息</button>
<script>const remote = require('@electron/remote');const { ipcRenderer } = require('electron');// 在渲染進程中創建一個新的窗口(win2)document.querySelector('#makeNewWindow').addEventListener('click', function () {win2 = new remote.BrowserWindow({webPreferences: {nodeIntegration: true,contextIsolation: false}});win2.loadFile('win2.html');win2.webContents.openDevTools();// 獲取 窗口(win2) 的 webContents.id 并通過 ipcRenderer.sendTo 方法發送消息至 win2document.querySelector('#sendMsg').addEventListener('click', () => {ipcRenderer.sendTo(win2.webContents.id,'msg_win2', { name: 'xiaom' }, { name: 'xiaoh' });});});</script>

窗口(win2) win2.html 文件內容如下:

<h1>win2</h1>
<script>const { ipcRenderer } = require('electron');// 接收 窗口(win1) 發送來的消息ipcRenderer.on('msg_win2', (event, param1, param2) => {console.log(param1);console.log(param2);console.log(event.sender);});
</script>

結果展示:

結果展示

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/13410.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/13410.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/13410.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

白鯨開源CEO郭煒在2024 DataOps發展大會上獲聘專家

2024年5月15日&#xff0c;白鯨開源CEO郭煒在2024 DataOps發展大會上被正式聘任為DataOps專家&#xff0c;并獲得了榮譽證書。本次大會由中國通信標準化協會主辦&#xff0c;中關村科學城管委會提供支持&#xff0c;大數據技術標準推進委員會&#xff08;CCSATC601&#xff09;…

iisnginx環境一次奇怪的跨域問題解決經過

跨域問題描述&#xff1a; iis網站跨域、nginx 網站跨域 都已配置&#xff0c;訪問接口依然出現跨域問題。 錯誤提示&#xff1a; ccess to XMLHttpRequest at ‘https://xxx.com/gameapi/preserve/get/status’ from origin ‘https://cdn.xxx.com’ has been blocked by CO…

Python簡易信息管理系統

我們將通過一個實例來探討如何使用Python與MySQL數據庫進行交互&#xff0c;以構建一個簡單的學生信息管理系統。這個系統將能夠執行基本的CRUD&#xff08;創建(Create)、讀取(Retrieve)、更新(Update)、刪除(Delete)&#xff09;操作&#xff0c;以管理學生信息。我們將使用m…

Python爬蟲-批量爬取新能源汽車上牌量

前言 本文是該專欄的第27篇,后面會持續分享python爬蟲干貨知識,記得關注。 最近粉絲朋友咨詢新能源汽車上牌量數據的爬取方法,對此在本文中,筆者以某汽車平臺為例,通過python來實現對“新能源汽車上牌量”的數據進行抓取。 具體實現思路和詳細邏輯,筆者將在正文結合完整…

三豐云搭建QQ-bot的服務器-代碼實現(3)

網址&#xff1a;https://www.sanfengyun.com >> 三豐云免費云服務器 代碼實現 書接上回裝飾器&#xff0c;顯而易見&#xff0c;只有裝飾器還不完善&#xff0c;所以我們接著來補充代碼 首先定義一個 MyClient 類 class MyClient(botpy.Client):async def on_ready(…

Nacos :安裝配置、服務注冊

目錄 一、中文官網 二、配置 1、application.properties 2、啟動 Nacos 服務 3、訪問 Nacos 三、服務注冊 1、配置Nacos客戶端的pom依賴 2、添加服務配置信息 3、添加 Nacos 啟動注解 一、中文官網 Nacos官網 | Nacos 官方社區 | Nacos 下載 | Nacos 下載后直接解壓…

0X JavaSE-- ( 遍歷-- for each、Iterator 、)、

for each for each 語句是 JDK5 的新特征&#xff0c;主要用于遍歷數組、集合。 // collection 可以是數組/實現了 Iterable 接口的集合類 for(dataType variable : collection){ // 使用 item 進行操作 } // 遍歷二維數組// 初始化一個二維數組int[][] array {{1, 2, 3},{4…

GO語言核心30講 實戰與應用 (io包,bufio包,os包,網絡服務,http,性能分析)

原站地址&#xff1a;Go語言核心36講_Golang_Go語言-極客時間 一、io包中的接口和工具 1. strings.Builder、strings.Reader 和 bytes.Buffer 這些類型實現了 io 包的很多接口&#xff0c;目的是什么&#xff1f; 是為了提高不同程序實體之間的互操作性。 程序實體是指比如網…

瀏覽器插件Video Speed Controller(視頻倍速播放),與網頁自身快捷鍵沖突/重復/疊加的解決辦法

瀏覽器插件Video Speed Controller&#xff08;視頻倍速播放&#xff09;&#xff0c;與網站自身快捷鍵沖突/重復/疊加的解決辦法 插件介紹問題曾今嘗試的辦法今日發現插件列表中打開Video Speed Controller的設置設置頁面翻到下面&#xff0c;打開實驗性功能。將需要屏蔽的原網…

網絡工程師----第三十一天

DNS&#xff1a; DNS含義&#xff1a;DNS 是 Domain Name System&#xff08;域名解析系統&#xff09; 端口號&#xff1a;DNS為53&#xff08;UDP&#xff09; 域名的層次結構&#xff1a; 域名的分級&#xff1a; 域名服務器&#xff1a; 域名解析過程&#xff1a; 遞歸查…

PHP xdebug

使用場景 一臺MAC上安裝了phpstorm&#xff0c;虛擬機安裝了對應的web程序&#xff0c;需要調試。 坑點&#xff0c;網上教程太多&#xff0c;不如看官網&#xff0c;需要按照xdebug版本來配置php.ini https://www.jetbrains.com/help/phpstorm/2023.3/configuring-xdebug.htm…

【Java】HOT100+代碼隨想錄 動態規劃(上)背包問題

目錄 理論基礎 一、基礎題目 LeetCode509&#xff1a;斐波那契數 LeetCode70&#xff1a;爬樓梯 LeetCode746&#xff1a;使用最小花費爬樓梯 LeetCode62&#xff1a;不同路徑 LeetCode63&#xff1a;不同路徑ii LeetCode343&#xff1a;整數拆分 LeetCode96&#xff1a;不…

vue uniapp 小程序 判斷日期是今天(顯示時分秒)、昨天、本周的周幾、超出本周顯示年月日

效果圖&#xff1a; util.js /*** 轉換時間*/ const messageFormat (datetime) >{ let result "";let currentTime new Date();if(isToday(datetime)){result datetime.substring(11,16);}else if(isYesterday(datetime)){result "昨天";}else if(…

分層解耦-三層架構

分層解耦-三層架構 Controller&#xff1a;控制層&#xff0c;接收前端發送的請求&#xff0c;對請求進行處理&#xff0c;并響應數據 service&#xff1a;業務邏輯層&#xff0c;處理具體的業務邏輯 dao&#xff1a;數據訪問層&#xff08;持久層&#xff09;&#xff0c;負…

python爬蟲[簡易版]

python爬數據[簡易版] 對于每個網站的爬的原理基本是一樣的,但是具體的代碼寫法的區別就在于爬的數據中解析出想要的數據格式: 以爬取有道詞典中的圖片為例: 第一步:打開網站,分析圖片的數據源來自哪里, https://dict-subsidiary.youdao.com/home/content?invalid&pre…

操作系統磁盤管理類問題

例題&#xff1a;在磁盤上存儲數據的排列方式會影響1/0服務的總時間。假設每個磁道被劃分成10個物理塊&#xff0c;每個物理塊存放1個邏輯記錄。邏輯記錄R1,R2....R10存放在同一個磁道上&#xff0c;記錄的排列順序如下表所示&#xff1a; 假定磁盤的旋轉速度為10ms/周&#xf…

VMware虛擬機-安裝程序無法自動安裝virtual machine......_windows server 2008 R2

系統版本&#xff1a;windows server 2008 R2 問題-安裝程序無法自動安裝virtual machine… 在使用虛擬機安裝windows server 2008 R2系統中&#xff0c;安裝VMware Tools工具安祖啊寄給你失敗&#xff0c;提示安裝程序無法自動安裝virtual machine…&#xff0c;必須手動安裝…

從源頭到洞察:大數據時代的數據提取與分析實戰指南

隨著科技的飛速發展&#xff0c;大數據已經成為現代社會的核心驅動力之一。從商業決策到科學研究&#xff0c;從政策制定到個人生活&#xff0c;數據無處不在&#xff0c;影響著我們的每一個決策。然而&#xff0c;如何從海量的數據中提取有價值的信息&#xff0c;并轉化為深刻…

List類

什么是 List 在集合框架中&#xff0c; List 是一個接口&#xff0c;繼承自 Collection 。 Collection 也是一個接口 &#xff0c;該接口中規范了后序容器中常用的一些方法&#xff0c;具體如下所示&#xff1a; List 中提供了好的方法&#xff0c;具體如下&#xff1a; List…

Conda 常用命令大全

Conda 常用命令大全 配置源conda配置清華源pip配置清華源pip配置阿里源 環境管理創建一個新的虛擬環境列出虛擬環境激活虛擬環境退出虛擬環境刪除虛擬環境復制某個虛擬環境 conda包管理列出全部包安裝包卸載包 pip包管理列出全部包安裝包卸載包 其他命令查詢 conda 版本查看環境…