Electron小白入門自學筆記(一)

碼文不易啊,轉載請帶上本文鏈接呀,感謝感謝 //www.cnblogs.com/echoyya/p/14297176.html

一、從Hello Electron開始

  1. 創建一個空的文件夾,並創建入口 main.js 文件,index.html內容文件,

  2. 安裝electron

    • npm init -y:初始化配置文件 package.json

    • npm i electron

  3. main.js 文件

    • 引入模組,創建應用

    • 創建窗口

    • 載入內容

    • 打開調試工具(可選)

    • 關閉窗口及應用監聽

  4. 執行文件

    • 直接執行:electron main.js

    • 默認執行:electron .

    • package.json 添加執行腳本: “start”: “electorn main.js”, 執行:npm run start

    • 執行上述命令報錯解決:先可嘗試全局安裝,在執行命令,如若仍然報錯,可能需要配置腳本執行許可權

    windows下運行*.ps1腳本(powershell的腳本)的時候,需要設置執行許可權,PowerShell默認的執行策略就是Restricted,禁止任何腳本的執行。

    • 首先管理員身份運行 windows powershell ,輸入Get-ExecutionPolicy ,用於獲得當前的執行策略。

    • Set-ExecutionPolicy 命令設置/更改執行策略,選擇RemoteSigned這個執行策略,這個策略既安全又可以執行本地編寫的腳本

// main.js  引入模組
// app模組:控制應用的生命周期
// BrowserWindow模組: 創建瀏覽器窗口
const { app ,BrowserWindow} = require('electron');

//  path模組: node 的內置模組,用於拼接路徑
const path = require('path');

// 1.初始化應用之後,會觸發監聽ready 事件
app.on('ready',ny_createWindow)

let win;
// 創建窗口
function ny_createWindow(){
  // 1.1創建窗口
  win = new BrowserWindow({
    width:330,
    height:355,
    resizable:false, // 是否可改變寬高,默認true
    movable:false,   // 是否可拖拽,默認true
    webPreferences: {
      nodeIntegration: true, // 是否集成 Nodejs
      enableRemoteModule: true, // 是否允許渲染進程 調用主進程模組
    }
    // 1.為了在渲染進程中使用require(),還需要啟用 nodeIntegration 。
    // 2.從v9版本開始,remote除非將 enableRemoteModule 設置為true,否則不允許在渲染進程中使用。
  });

  // 1.2 載入內容
  // win.loadURL('//www.baidu.com')   // 遠程

  // __dirname: 當前js文件所在的文件夾路徑,絕對路徑
  // win.loadURL(path.join(__dirname, './index.html')) // 本地 相對路徑

  // mac 系統:需要拼接 file 協議
  // path.join('file://',__dirname,'./index.html')

  // 1.3 調試工具
  win.webContents.openDevTools(); // webContents: 控制和渲染頁面的

  // 1.4 關閉窗口, 關閉窗口前想做的事
  win.on('close',function(){
    win = null;  // 關閉窗口
    app.quit();  // 關閉應用
  })

二、製作設置菜單 Menu

  1. 創建menu.js ,引入模板,創建菜單模板

  2. 構建菜單(實例化一個菜單對象)

  3. 設置菜單對象到應用中

  4. 用到的方法:buildFromTemplate , setApplicationMenu

  5. 選項:

    • type:(‘normal’ | ‘separator’ | ‘submenu’ | ‘checkbox’ | ‘radio’)
    • label:標題
    • accelerator:快捷鍵,區分 mac 及 win
    • submenu:子菜單
    • click:點擊事件
  6. main.js中引用: require('./menu');

// menu.js  引入模板
const { Menu } = require('electron')

// 1.設置一個模板
let template = [
  {
    label:'文件',
    submenu:[
      {
        label:'新建文件',
        accelerator:'ctrl+N',
        click:function(){
          console.log('new file')
        }
      },
      {
        type:'separator'
      },
      {
        label:'新建窗口',
        accelerator:(function(){
          if(process.platform =='darwin'){  //mac 基於darwin
            return 'alt+command+M'
          }else{ //win
            return 'alt+ctrl+M'
          }
        })(),
        click:function(){
          console.log('new window')
        }
      },
      {
        type:'separator'
      },
      {
        label:'自動保存',
        accelerator:'ctrl+S',
        type:'checkbox',
        checked:true,
        click:function(){
          console.log('saved')
        }
      },
    ]
  },
  {
    label:'編輯'
  },
]

// 2. 構建菜單(實例化一個菜單對象) 
const menu = Menu.buildFromTemplate(template);

//3. 設置菜單對象到應用中
Menu.setApplicationMenu(menu);

三、主進程(Main Process)和渲染進程(Render Process)

主進程

在Electron中,入口是一個js文件,運行這個入口文件的進程稱作主進程。

(通常會是package.json里的main腳本,一般是main.js)

在主進程使用BrowserWindow模組可以創建並管理web頁面,也就是應用的GUI(圖形介面)

const { BrowserWindow } = require('electron');
const path = require('path');

// 主進程創建web頁面
let win = new BrowserWindow({...});

// 載入本地文件
// win.loadURL(path.join('file://',__dirname, './index.html'))  // mac
win.loadURL(path.join(__dirname, './index.html'))
  

渲染進程

在主進程創建的每一個web頁面也都運行著自己的進程,頁面引入的js文件就屬於渲染進程。

渲染進程各自管理自己的頁面,可以想像是瀏覽器的一個個的tab。

electron核心可以分成2個部分,主進程渲染進程。主進程連接著作業系統和渲染進程,可以看做頁面和電腦溝通的橋樑。渲染進程就是我們所熟悉前端環境了。只是載體改變了,從瀏覽器變成了window。傳統的web環境我們是不能對用戶的系統進行操作的。而electron相當於node環境,可以在項目里使用所有的node api 。

簡單理解:
給web項目套上一個node環境的殼。

四、在渲染進程中創建一個子窗口

  1. 創建渲染進程對應render.js文件

  2. 渲染進程引入BrowserWindow模組,需要藉助於remote模組,

    • 渲染進程不能直接使用 BrowserWindow ,因為該模組默認是主進程允許使用的
    • 藉助 remote ,從中引入主進程中的模組,需要在主進程窗口中配置 enableRemoteModule,允許渲染進程 調用主進程模組
  3. 並在index.html中引入render.js,兩種引入方法及區別

    <!-- 1.引入render.js -->
    <script src="./render-process/render.js"></script>
     
    <!-- 2.electron 基於node -->
    <script>
        require('./render-process/render.js');
    </script>
      
    <--   
     區別:
     	src: 是全局變數
     	require: 引入的文件的最外層的變數,不是全局變數,註:為了在渲染進程中使用require(),還需在主進程窗口配置中啟用 nodeIntegration 。
     	//main.js
         win = new BrowserWindow({
            width:330,
            height:355,
            resizable:false, // 是否可改變寬高,默認true
            movable:false,   // 是否可拖拽,默認true
            webPreferences: {
                  nodeIntegration: true, // 是否集成 Nodejs
                  enableRemoteModule: true, // 是否允許渲染進程 調用主進程模組
              }
         })    
      使用:
         1.元素綁定onclick事件 ==== src引入
         2.require  ==== 給元素綁定一個ID ,在render.js獲取元素並綁定事件
    -->
    

五、進程間通訊

在electron下,主進程與渲染進程相互通訊要通過ipc(Inter-Process Communication),進程間通訊模組來完成,

主進程與渲染進程調用的ipc模組是不一樣的:

  • 主進程調用ipcMain

  • 渲染進程調用ipcRenderer

A. 渲染進程 給 主進程 發送指令

  1. ipcRenderer模組:渲染進程引入,用於發送事件給主進程,和監聽主進程返回的回復事件

    • const { ipcRenderer } = require('electron');

    • 發送事件:ipcRenderer.send('事件名稱',傳遞的數據);

    • 監聽事件:ipcRenderer.on('監聽事件名稱',接收的數據);

  2. ipcMain模組:主進程引入,用於接收渲染進程發送的事件並進行回復

    • const { ipcMain } = require('electron');

    • 監聽事件:ipcMain.on('監聽事件名稱',接收的數據);

index.html:

<h1>Hello Electron!</h1>
<button onclick="ny_click()">click me</button>

<!-- 引入render.js 渲染進程-->
<script src="./render-process/render.js"></script>

render.js:

function ny_click(){
  console.log('Render:','Echoyya')
  ipcRenderer.send('myName','Echoyya');
}

main.js:

ipcMain.on('myName',function(event,msg){
  console.log('Main:',msg);
})

運行結果:主進程輸出結果會列印在終端,而渲染進程輸出結果會列印在調試工具中

B. 主進程 給 渲染進程 發送指令

了解了 渲染進程 -> 主進程 後,反之就很好理解和掌握了,大同小異,簡單總結一下:

  1. main.js 發送指令 兩種方式:

    ipcMain.on('myName',function(event,msg){
      // 1. 通過event 
      //event.sender.send('msg-b','程式媛');
      
      // 2. 通過webContents (推薦)
      win.webContents.send('msg-b','程式媛'); 
    })
    
  2. render.js 渲染進程接收指定

    ipcRenderer.on('msg-b',function (event, msg) {
    	console.log('Render:',msg)
    });
    

    運行結果

C. 渲染進程 給 渲染進程 發送指令

思路:渲染進程 -> 主進程 -> 渲染進程

a.js: ipcRenderer.send('dataToMain','渲染進程 -> 主進程 -> 渲染進程')

main.js:

ipcMain.on('dataToMain',function(event,data){
	win.webContents.send('dataToRender',data);
})

b.js:

 ipcRenderer.on('dataToRender', function (event, data) {
	console.log(data)
 })

D. 不同渲染進程之間數據共享

  1. 可以很簡單的使用H5的api來完成,如localStorage,sessionStorage,但今天要說的是另一種

  2. 在主進程中將一個對象儲存為全局變數,然後通過remote模組操作

    • 創建a.js , b.js,並在index.html中引入

index.html:

<button id="btn1">改變數據</button>
<button id="btn2">獲取數據</button>
	
<script>
	require('./render-process/a.js');
	require('./render-process/b.js');
</script>

main.js:

// 全局變數
global.shareObject = {
  name:'上海'
}

a.js:

const remote = require('electron').remote;

let btn1 = document.getElementById('btn1');

btn1.onclick = function(){
  
  remote.getGlobal('shareObject').name = '北京';
  
  console.log('has changed');

}

b.js:

const remote = require('electron').remote;

let btn2 = document.getElementById('btn2');

btn2.onclick = function(){

  let msg = remote.getGlobal('shareObject').name

  console.log(msg)

}

六、提示框 dialog 模組

  1. 首先dialog模組是主進程可使用模組

  2. 調用語法:dialog.showMessageBox({ ... }),版本升級後不支援原來的回調方法,改為返回promise對象

  3. 常用配置對象參數:

    • type:類型(error/info)
    • title:標題
    • message:提示資訊
    • icon:本地圖標(需使用nativeImage模組,且主進程與渲染進程均可用該模組)
    • buttons:按鈕(數組類型)
const { dialog ,nativeImage} = require('electron');
const path = require('path');
 
// 1.資訊對話框
dialog.showMessageBox({
  title:'溫馨提示',
  message:'XXXXX XXXXX XXXXX XXXXX XXXXX',
  buttons:['Yes','No'],
  icon:nativeImage.createFromPath(path.join(__dirname,'../src/img/icon1.png'))
}).then(function(index){
  if(index.response == 0){ // 點擊了Yes按鈕
    console.log('I want you !');
  }else{ // 點擊了No按鈕
    console.log('no no no');
  }
});

// 2.錯誤提示框
dialog.showErrorBox('1213','訪問錯誤')

七、打包(electron-packager)

打包必要元素及格式輸入:electron-packager <應用目錄> <應用名稱> <打包平台> –out=<輸出目錄> <架構> <應用版本> <忽略文件> <圖標> –overwrite

執行上述命令,可在輸出目錄中,打包成功一個exe 可執行文件,此命令區分mac及win,設備原因,此處僅演示win系統打包,mac系統的同學,需自行查找相關資料!!!

package.json:

"scripts": {
	"start": "electorn main.js", 
	"pack":"electron-packager ./  test --platform=win32 --out=./dist --arch=x64 --app-version=1.0.0 --ignore=node_modules --icon=./src/img/hrbb.ico --overwrite "
},

Tags: