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

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

1、從Hello Electron開始

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

  2. 安裝electron前端

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

    • npm i electronweb

  3. main.js 文件shell

    • 引入模塊,建立應用npm

    • 建立窗口json

    • 加載內容windows

    • 打開調試工具(可選)api

    • 關閉窗口及應用監聽數組

  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('http://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();  // 關閉應用
  })

2、製做設置菜單 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);

3、主進程(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環境的殼。

4、在渲染進程中建立一個子窗口

  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獲取元素並綁定事件
    -->

5、進程間通訊

在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)

}

6、提示框 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','訪問錯誤')

7、打包(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 "
},

相關文章
相關標籤/搜索