Electron構建跨平臺應用

1、前言

  • NW.jsElectron 均可以用前端的知識來開發桌面應用。NW.jsElectron起初是同一 個做者開發。後來種種緣由分爲兩個產品。一個命名爲 NW.js(英特爾公司提供技術支持)、 另外一命名爲 Electron(Github 公司提供技術支持)。
  • NW.jsElectron 能夠用 Nodejs 中幾乎全部的模塊。NW.jsElectron不只能夠把 html 寫的 web 頁面打包成跨平臺能夠安裝到電腦上面的軟件,也能夠經過 javascript 訪問操做 系統原生的 UIApi(控制窗口、添加菜單項目、托盤應用菜單、讀寫文件、訪問剪貼板)。

githubatom 編輯器、微軟的 vscode 編輯器,包括阿里內部的一些 軟件也是用 electron 開發的javascript

1. Electron 是由誰開發的?css

Electron 是由 Github 開發html

2. Electron 是什麼?前端

Electron 是一個用 HTMLCSSJavaScript 來構建跨平臺桌面應用程序的一個開源庫vue

3. Electron 把 HTML,CSS 和 JavaScript 組合的程序構建爲跨平臺桌面應用程序的原理 是什麼?java

原理爲 Electron 經過將 ChromiumNode.js 合併到同一個運行時環境中,並將其打包爲 MacWindowsLinux 系統下的應用來實現這一目的。node

4. Electron 什麼時候出現的,爲何會出現?webpack

Electron2013 年做爲構建 Atom 的框架而被開發出來。這兩個項目在 2014 春季開源。 (Atom:爲 Github 上可編程的文本編輯器)ios

一些歷史:git

  • 20134Atom Shell 項目啓動 。
  • 20145Atom Shell 被開源 。
  • 20154Atom Shell 被重命名爲 Electron
  • 20165Electron 發佈了 v1.0.0 版本

5. Electron 當前流行程度?

目前 Electron 已成爲開源開發者、初創企業和老牌公司經常使用的開發工具。

6. Electron 當前由那些人在維護支持?

Electron 當前由 Github 上的一支團隊和一羣活躍的貢獻者維護。有些貢獻者是獨立開發者,有些則在用 Electron 構建應用的大型公司裏工做。

7. Electron 新版本多久發佈一次?

Electron 的版本發佈至關頻繁。每當 ChromiumNode.js 有重要的 bug 修復,新 API 或是版本更新時 Electron 會發布新版本。

  • 通常 Chromium 發行新的穩定版後的一到兩週以內,ElectronChromium 的版本會對其進行更新,具體時間根據升級所需的工做量而定。
    通常 Node.js 發行新的穩定版一個月後,ElectronNode.js 的版本會對其進行更新,具 體時間根據升級所需的工做量而定。

8. Electron 的核心理念是什麼?

Electron 的核心理念是:保持 Electron 的體積小和可持續性開發。
如:爲了保持 Electron 的小巧 (文件體積) 和可持續性開發 (以防依賴庫和 API 的泛濫) , Electron 限制了所使用的核心項目的數量。
好比 Electron 只用了 Chromium 的渲染庫而不是其所有組件。這使得升級 Chromium 更加容易,但也意味着 Electron 缺乏了 Google Chrome 裏的一些瀏覽器相關的特性。 添加到 Electron 的新功能應該主要是原生 API。 若是能夠的話,一個功能應該儘量的成 爲一個 Node.js 模塊。

9. Electron 當前的最新版本爲多少?

Electron 當前的最新版本爲 4.0.1 (當前時間爲 201916 號)

2、環境搭建

1. 安裝 electron

npm install -g electron

2. 克隆一個倉庫、快速啓動一個項目

# 克隆示例項目的倉庫
git clone https://github.com/electron/electron-quick-start

# 進入這個倉庫
cd electron-quick-start

# 安裝依賴並運行
npm install && npm start

 

3. 手動搭建一個 electron 項目

  1. 新建一個項目目錄 例如: electrondemo01
  2. electrondemo01 目錄下面新建三個文件: index.htmlmain.jspackage.json
  3. index.html 裏面用 css 進行佈局(之前怎麼寫如今仍是怎麼寫)
  4. main.js 中寫以下代碼
var electron =require('electron'); //electron 對象的引用
const app=electron.app; //BrowserWindow 類的引用
const BrowserWindow=electron.BrowserWindow;

let mainWindow=null; //監聽應用準備完成的事件 app.on('ready',function(){

//監聽應用準備完成的事件
app.on('ready',function(){
    //建立窗口
    mainWindow=new BrowserWindow({width: 800, height: 600}); mainWindow.loadFile('index.html');
    
    mainWindow.on('closed', function () {
        mainWindow = null; })
    })
})

//監聽全部窗口關閉的事件 
app.on('window-all-closed', function () {
    // On OS X it is common for applications and their menu bar // to stay active until the user quits explicitly with Cmd + Q 
    if (process.platform !== 'darwin') {
        app.quit(); 
    }
})

 

  1. 運行
electron . #注意:命令後面有個點

4. electron-forge 搭建一個 electron 項目

electron-forge 至關於 electron 的一個腳手架,可讓咱們更方便的建立、運行、打包 electron 項目

npm install -g electron-forge 

electron-forge init my-new-app 

cd my-new-app

npm start

 

3、Electron 運行流程

3.1 Electron 運行的流程

 
image.png

3.2 Electron 主進程和渲染進程

  • Electron 運行 package.jsonmain 腳本的進程被稱爲主進程。
  • 在主進程中運行的腳本經過建立 web 頁面來展現用戶界面。 一個 Electron 應用老是有且只有一個主進程。
  • 因爲 Electron 使用了 Chromium(谷歌瀏覽器)來展現 web 頁面,因此 Chromium 的 多進程架構也被使用到。 每一個 Electron 中的 web 頁面運行在它本身的渲染進程中。
  • 主進程使用 BrowserWindow 實例建立頁面。每一個 BrowserWindow 實例都在本身的渲 染進程裏運行頁面。 當一個 BrowserWindow實例被銷燬後,相應的渲染進程也會被終止
 
image.png
 
image.png
  • 進程:進程是計算機中的程序關於某數據集合上的一次運行活動,是 系統進行資源分配和調度的基本單位,是操做系統結構的基礎。
  • 線程:在一個程序裏的一個執行路線就叫作線程(thread)。更準確的定義是: 線程是「一個進程內部的控制序列」。
  • 線程和進程:一個程序至少有一個進程,一個進程至少有一個線程

3.3 Electron 渲染進程中經過 Nodejs 讀取本地文件

在普通的瀏覽器中,web頁面一般在一個沙盒環境中運行,不被容許去接觸原生的資源。 然而 Electron 的用戶在 Node.jsAPI支持下能夠在頁面中和操做系統進行一些底層交 互。
Nodejs 在主進程和渲染進程中均可以使用。渲染進程由於安全限制,不能直接操做生 GUI。雖然如此,由於集成了 Nodejs,渲染進程也有了操做系統底層 API的能力,Nodejs 中經常使用的 PathfsCrypto 等模塊在 Electron 能夠直接使用,方便咱們處理連接、路徑、 文件 MD5 等,同時 npm 還有成千上萬的模塊供咱們選擇。

var fs = require('fs');
var content = document.getElementById('content'); 
var button = document.getElementById('button');

button.addEventListener('click',function(e){
    fs.readFile('package.json','utf8',function(err,data){ 
        content.textContent = data;
        console.log(data);
    }); 
});

 

3.4 Electron 開啓調試模式

mainWindow.webContents.openDevTools(); 
 
image.png

4、Electron 模塊介紹

Electron 模塊介紹、remote 模塊、通 過 BrowserWindow 打開新窗口

4.1 Electron 主進程和渲染進程中的模塊

 
image.png

4.2 Electron remote 模塊

remote 模塊提供了一種在渲染進程(網頁)和主進程之間進行進程間通信(IPC)的簡便途徑

Electron 中, 與 GUI 相關的模塊(如 dialog, menu 等)只存在於主進程,而不在渲染進程中 。爲了能從渲染進程中使用它們,須要用ipc模塊來給主進程發送進程間消息。使用 remote 模塊,能夠調用主進程對象的方法,而無需顯式地發送進程間消息,這相似於 JavaRMI

4.3 經過BrowserWindow 打開新窗口

Electron 渲染進程中經過 remote 模塊調用主進程中的 BrowserWindow 打開新窗口

https://electronjs.org/docs/api/browser-window

// 主進程代碼
const electron = require('electron'); 

// 控制應用生命週期的模塊 
const {app} = electron;

// 建立本地瀏覽器窗口的模塊 
const {BrowserWindow} = electron;

// 指向窗口對象的一個全局引用,若是沒有這個引用,那麼當該 javascript 對象被垃圾回收 的
// 時候該窗口將會自動關閉
let win;

function createWindow() {
    // 建立一個新的瀏覽器窗口
    win = new BrowserWindow({width: 1104, height: 620});//570+50
    
    // 而且裝載應用的 index.html 頁面
    win.loadURL(`file://${__dirname}/html/index.html`);
    
    // 打開開發工具頁面
    win.webContents.openDevTools();
    
    //當窗口關閉時調用的方法
    win.on('closed', () => {
        // 解除窗口對象的引用,一般而言若是應用支持多個窗口的話,你會在一個數組裏 // 存放窗口對象,在窗口關閉的時候應當刪除相應的元素。
        win = null;
    });
}

// 當 Electron 完成初始化而且已經建立了瀏覽器窗口,則該方法將會被調用。
// 有些 API 只能在該事件發生後才能被使用
app.on('ready', createWindow);

// 當全部的窗口被關閉後退出應用 
app.on('window-all-closed', () => {
    // 對於 OS X 系統,應用和相應的菜單欄會一直激活直到用戶經過 Cmd + Q 顯式退出 
    if (process.platform !== 'darwin') {
        app.quit(); 
    }
});


app.on('activate', () => {
    // 對於 OS X 系統,當 dock 圖標被點擊後會從新建立一個 app 窗口,而且不會有其餘
    // 窗口打開
    if (win === null) {
        createWindow(); 
    }
});

// 在這個文件後面你能夠直接包含你應用特定的由主進程運行的代碼。 
// 也能夠把這些代碼放在另外一個文件中而後在這裏導入
// 渲染進程代碼 /src/render/index.js
// 打開新窗口屬性用法有點相似vscode打開新的窗口

const btn = document.querySelector('#btn');
const path = require('path');
const BrowerWindow = require('electron').remote.BrowserWindow;

btn.onclick = () => {
    win = new BrowerWindow({ 
        width: 300,
        height: 200, 
        frame: false, // false隱藏關閉按鈕、菜單選項 true顯示
        fullscreen:true, // 全屏展現
        transparent: true 
    }) 

    win.loadURL(path.join('file:',__dirname,'news.html'));

    win.on('close',()=>{win = null});
}

 

 
image.png

5、自定義頂部菜單/右鍵菜單

 
image.png

5.1 主進程中調用Menu模塊-自定義軟件頂部菜單

https://electronjs.org/docs/api/menu-item

ElectronMenu 模塊能夠用來建立原生菜單,它可用做應用菜單和 context 菜單

這個模塊是一個主進程的模塊,而且能夠經過 remote 模塊給渲染進程調用

// main/menu.js
const { Menu }  = require('electron')

// 文檔 https://electronjs.org/docs/api/menu-item
// 菜單項目
let menus = [
    {
        label: '文件',
        submenu: [
            {
                label: '新建文件',
                accelerator: 'ctrl+n', // 綁定快捷鍵
                click: function () { // 綁定事件
                    console.log('新建文件')
                }
            },
            {
                label: '新建窗口',
                click: function () {
                    console.log('新建窗口')
                }
            }
        ]
    },
    {
        label: '編輯',
        submenu: [
            {
                label: '複製',
                role: 'copy' // 調用內置角色實現對應功能
            },
            {
                label: '剪切',
                role: 'cut'  // 調用內置角色實現對應功能
            }
        ]
    },
    {
        label: '視圖',
        submenu: [
            {
                label: '瀏覽'
            },
            {
                label: '搜索'
            }
        ]
    }
]

let m = Menu.buildFromTemplate(menus)
Menu.setApplicationMenu(m)
// 在主進程src/index.js中引入
const createWindow = () => {

  // 建立菜單  
  // 引入菜單模塊
  require('./main/menu.js')
};

 

 
image.png

咱們給菜單綁定事件,在命令行控制檯能夠看到

 
image.png

5.2 渲染進程中調用Menu模塊

不推薦使用這種方式,建議在主進程中使用

1. remote

經過remote調用主進程的方法

// 菜單引入的方式發生變化
const { Menu }  = require('electron').remote

// 其餘代碼和上面菜單同樣
// ...

 

2. 加入index.html

<script src="render/menu.js"></script> 

5.3 渲染進程中自定義右鍵菜單

1. 定義菜單

// render/menu.js

// 在渲染進程中經過remote模塊調用主進程中的模塊
const { Menu }  = require('electron').remote
const { remote } = require('electron')

// 文檔 https://electronjs.org/docs/api/menu-item
// 菜單項目
let menus = [
    {
        label: '文件',
        submenu: [
            {
                label: '新建文件',
                accelerator: 'ctrl+n', // 綁定快捷鍵
                click: function () { // 綁定事件
                    console.log('新建文件')
                }
            },
            {
                label: '新建窗口',
                click: function () {
                    console.log('新建窗口')
                }
            }
        ]
    },
    {
        label: '編輯',
        submenu: [
            {
                label: '複製',
                role: 'copy' // 調用內置角色實現對應功能
            },
            {
                label: '剪切',
                role: 'cut'  // 調用內置角色實現對應功能
            }
        ]
    },
    {
        label: '視圖',
        submenu: [
            {
                label: '瀏覽'
            },
            {
                label: '搜索'
            }
        ]
    }
]

let m = Menu.buildFromTemplate(menus)
// Menu.setApplicationMenu(m)

// 綁定右鍵菜單
window.addEventListener('contextmenu', (e)=>{
   e.preventDefault()
   m.popup({
    window: remote.getCurrentWindow()
   })
}, false)

 

 
image.png

2. 引入

<!--index.html--> <script src="render/menu.js"></script> 

6、進程通訊

 
image.png

6.1 主進程與渲染進程之間的通訊

有時候咱們想在渲染進程中經過一個事件去執行主進程裏面的方法。或者在渲染進程中通知 主進程處理事件,主進程處理完成後廣播一個事件讓渲染進程去處理一些事情。這個時候就 用到了主進程和渲染進程之間的相互通訊

Electron 主進程,和渲染進程的通訊主要用到兩個模塊:ipcMainipcRenderer

  • ipcMain:當在主進程中使用時,它處理從渲染器進程(網頁)發送出來的異步和同步信息,固然也有可能從主進程向渲染進程發送消息。
  • ipcRenderer: 使用它提供的一些方法從渲染進程 (web 頁面) 發送同步或異步的消息到主進程。 也能夠接收主進程回覆的消息

6.1.1 渲染進程給主進程發送異步消息

間接實現渲染進程執行主進程裏面的方法

1. 引入ipcRender

<!--src/index.html-->
<button id="send">在 渲染進程中執行主進程裏的方法(異步)</button>
<script src="render/ipcRender.js"></script>

 

2. 引入ipcMain

// 在主進程src/index.js中引入
const createWindow = () => {

  // 建立菜單  
  // 引入菜單模塊
  require('./main/ipcMain.js')
};

 

3. 渲染進程發送消息

// src/render/ipcRender.js
//渲染進程

let send = document.querySelector('#send');
const { ipcRenderer } = require('electron');

send.onclick = function () {
    // 傳遞消息給主進程
    // 異步
    ipcRenderer.send('sendMsg', {name:'poetries', age: 23})
}

 

2. 主進程接收消息

// src/main/ipcMain.js

//主進程

const { ipcMain }  = require('electron')

// 主進程處理渲染進程廣播數據
ipcMain.on('sendMsg', (event, data)=> {
    console.log('data\n ', data)
    console.log('event\n ', event)
})

 

 
image.png

6.1.2 渲染進程發送消息,主進程接收消息並反饋

渲染進程給主進程發送異步消息,主進程接收到異步消息之後通知渲染進程

1. 引入ipcRender

<!--src/index.html-->
<button id="sendFeedback">在 渲染進程中執行主進程裏的方法,並反饋給主進程(異步)</button>
<script src="render/ipcRender.js"></script>

 

2. 引入ipcMain

// 在主進程src/index.js中引入
const createWindow = () => {

  // 建立菜單  
  // 引入菜單模塊
  require('./main/ipcMain.js')
};

 

3. 渲染進程發送消息

// src/render/ipcRender.js

//渲染進程
let sendFeedback = document.querySelector('#sendFeedback');

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

// 向主進程發送消息
sendFeedback.onclick = function () {
    // 觸發主進程裏面的方法
    ipcRenderer.send('sendFeedback', {name:'poetries', age: 23})
}

 

4. 主進程收到消息處理並廣播反饋通知渲染進程

// src/main/ipcMain.js

//主進程
const { ipcMain }  = require('electron')


// 主進程處理渲染進程廣播數據,並反饋給渲染進程
ipcMain.on('sendFeedback', (event, data)=> {
    // console.log('data\n ', data)
    // console.log('event\n ', event)
    
    // 主進程給渲染進程廣播數據
    event.sender.send('sendFeedbackToRender', '來自主進程的反饋')
})

 

5. 渲染進程處理主進程廣播的數據

// src/render/ipcRender.js
// 向主進程發送消息後,接收主進程廣播的事件
ipcRenderer.on('sendFeedbackToRender', (e, data)=>{
    console.log('event\n ', e)
    console.log('data\n ', data)
})

 

 
image.png

6.1.3 渲染進程給主進程發送同步消息

1. 引入ipcRender

<!--src/index.html-->
 <button id="sendSync">渲染進程和主進程同步通訊</button>
<script src="render/ipcRender.js"></script>

 

2. 引入ipcMain

// 在主進程src/index.js中引入
const createWindow = () => {

  // 建立菜單  
  // 引入菜單模塊
  require('./main/ipcMain.js')
};

 

3. 渲染進程給主進程同步通訊

// src/render/ipcMain.js
let sendSync = document.querySelector('#sendSync');

// 渲染進程和主進程同步通訊
sendSync.onclick = function () {
    // 同步廣播數據
   let msg =  ipcRenderer.sendSync('sendsync', {name:'poetries', age: 23})
    
   // 同步返回主進程反饋的數據
   console.log('msg\n ', msg)
}

 

4. 主進程接收數據處理

// src/main/ipcMain.js

// 渲染進程和主進程同步通訊 接收同步廣播
ipcMain.on('sendsync', (event, data)=> {
    // console.log('data\n ', data)
    // console.log('event\n ', event)
    // 主進程給渲染進程廣播數據
    event.returnValue ='渲染進程和主進程同步通訊 接收同步廣播,來自主進程的反饋.';
})

 

 
image.png

6.1.4 渲染進程廣播通知主進程打開窗口

通常都是在渲染進程中執行廣播操做,去通知主進程完成任務

1. 引入openWindow

<!--src/index.html-->
 <button id="sendSync">渲染進程和主進程同步通訊</button>
<script src="render/openWindow.js"></script>

 

2. 引入ipcMain2

// 在主進程src/index.js中引入
const createWindow = () => {

  // 建立菜單  
  // 引入菜單模塊
  require('./main/ipcMain2.js')
};

 

3. 渲染進程通知主進程打開窗口

// src/render/openWindow.js

/* eslint-disable */
let openWindow = document.querySelector('#openWindow');

var { ipcRenderer } = require('electron');

// 渲染進程和渲染進程直接的通訊========
openWindow.onclick = function () {
    // 經過廣播的形式 通知主進程執行操做
    ipcRenderer.send('openwindow', {name:'poetries', age: 23})
}

 

4. 主進程收到通知執行操做

// src/main/ipcMain2.js

/* eslint-disable */
let { ipcMain,BrowserWindow } = require('electron')
const path = require('path')

let win;

// 接收到廣播
ipcMain.on('openwindow', (e, data)=> {
    // 調用window打開新窗口
    win = new BrowserWindow({
        width: 400,
        height: 300,
    });
    win.loadURL(path.join('file:',__dirname, '../news.html'));
    win.webContents.openDevTools()
    win.on('closed', () => {
        win = null;
      });
})

 

 
image.png

6.2 渲染進程與渲染進程之間的通訊

也就是兩個窗口直接的通訊

6.2.1 localstorage傳值

Electron 渲染進程經過 localstorage 給另外一個渲染進程傳值

1. 引入openWindow

<!--src/index.html-->
 <button id="sendSync">渲染進程和主進程同步通訊</button>
<script src="render/openWindow.js"></script>

 

2. 引入ipcMain2

// 在主進程src/index.js中引入
const createWindow = () => {

  // 建立菜單  
  // 引入菜單模塊
  require('./main/ipcMain2.js')
};

 

3. 渲染進程通知主進程打開窗口

// src/render/openWindow.js

/* eslint-disable */
let openWindow = document.querySelector('#openWindow');

var { ipcRenderer } = require('electron');

// 渲染進程和渲染進程直接的通訊========
openWindow.onclick = function () {
    // 經過廣播的形式 通知主進程執行操做
    ipcRenderer.send('openwindow', {name:'poetries', age: 23})
    
    // ======= localstorage傳值 =====
     localStorage.setItem('username', 'poetries')
}

 

4. 新建news頁面

<!--src/news.html-->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    news page
  </body>
  <script src="render/news.js"></script>
</html>
// src/render/news.js

let username = localStorage.getItem('username')
console.log(username)

 

5. 主進程收到通知執行操做

// src/main/ipcMain2.js

/* eslint-disable */
let { ipcMain,BrowserWindow } = require('electron')
const path = require('path')

let win;

// 接收到廣播
ipcMain.on('openwindow', (e, data)=> {
    // 調用window打開新窗口
    win = new BrowserWindow({
        width: 400,
        height: 300,
    });
    win.loadURL(path.join('file:',__dirname, '../news.html'));
    win.webContents.openDevTools()
    win.on('closed', () => {
        win = null;
      });
})

 

6.2.2 BrowserWindow和webContents方式實現

經過 BrowserWindowwebContents 模塊實現渲染進程和渲染進程的通訊

webContents 是一個事件發出者.它負責渲染並控制網頁,也是 BrowserWindow 對象的屬性

須要瞭解的幾個知識點

  1. 獲取當前窗口的 id
const winId = BrowserWindow.getFocusedWindow().id;

 

  1. 監聽當前窗口加載完成的事件
win.webContents.on('did-finish-load',(event) => {
    
})
  1. 同一窗口之間廣播數據
win.webContents.on('did-finish-load',(event) => {
    win.webContents.send('msg',winId,'我是 index.html 的數據');
})

 

  1. 經過 id 查找窗口
let win = BrowserWindow.fromId(winId);

 

下面是具體演示

1. 引入openWindow

<!--src/index.html-->
 <button id="sendSync">渲染進程和主進程同步通訊</button>
<script src="render/openWindow.js"></script>

 

2. 引入ipcMain2

// 在主進程src/index.js中引入
const createWindow = () => {

  // 建立菜單  
  // 引入菜單模塊
  require('./main/ipcMain2.js')
};

 

3. 渲染進程通知主進程打開窗口

// src/render/openWindow.js

/* eslint-disable */
let openWindow = document.querySelector('#openWindow');

var { ipcRenderer } = require('electron');

// 渲染進程和渲染進程直接的通訊========
openWindow.onclick = function () {
    // 經過廣播的形式 通知主進程執行操做
    ipcRenderer.send('openwindow', {name:'poetries', age: 23})
}

 

4. 主進程收到通知執行操做

// src/main/ipcMain2.js

let { ipcMain,BrowserWindow } = require('electron')
const path = require('path')

let win;

// 接收到廣播
ipcMain.on('openwindow', (e, userInfo)=> {
    // 調用window打開新窗口
    win = new BrowserWindow({
        width: 400,
        height: 300,
    });
    win.loadURL(path.join('file:',__dirname, '../news.html'));

    // 新開窗口調試模式
    win.webContents.openDevTools()

    // 把渲染進程傳遞過來的數據再次傳遞給渲染進程news
    // 等待窗口加載完
    win.webContents.on('did-finish-load', ()=>[
        win.webContents.send('toNews', userInfo)
    ])
    

    win.on('closed', () => {
        win = null;
      });
})

 

5. news接收主進程傳遞的數據

數據通過渲染進程->主進程->news渲染進程

<!--news頁面-->
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
  </head>
  <body>
    news page
  </body>
  <script src="render/news.js"></script>
</html>
// src/render/news.js

var { ipcRenderer } = require('electron');

// let username = localStorage.getItem('username')
// console.log(username)

// 監聽主進程傳遞過來的數據 
ipcRenderer.on('toNews',(e, userInfo)=>{
    console.log(userInfo)
})

 

 
 
image.png
 
image.png

那麼,這裏有一個問題,news進程接收到了廣播後如何給出反饋呢?

 
image.png

1. 在主進程中獲取窗口ID傳遞

// src/main/ipcMain2.js


let { ipcMain,BrowserWindow } = require('electron')
const path = require('path')

let win;

// 接收到廣播
ipcMain.on('openwindow', (e, userInfo)=> {
      // 獲取當前窗口ID 放在第一行保險  由於後面也打開了新窗口使得獲取的ID有問題
    let winId = BrowserWindow.getFocusedWindow().id

    // 調用window打開新窗口
    win = new BrowserWindow({
        width: 400,
        height: 300,
    });
    win.loadURL(path.join('file:',__dirname, '../news.html'));

    // 新開窗口調試模式
    win.webContents.openDevTools()

  

    // 把渲染進程傳遞過來的數據再次傳遞給渲染進程news
    // 等待窗口加載完
    win.webContents.on('did-finish-load', ()=>[
        win.webContents.send('toNews', userInfo, winId)
    ])
    

    win.on('closed', () => {
        win = null;
      });
})

 

2. 在news進程中廣播數據

// src/render/news.js

var { ipcRenderer } = require('electron');

// 注意這裏 在渲染進程中須要從remote中獲取BrowserWindow
const BrowerWindow = require('electron').remote.BrowserWindow;

// let username = localStorage.getItem('username')
// console.log(username)

// 監聽主進程傳遞過來的數據 
ipcRenderer.on('toNews',(e, userInfo, winId)=>{
    // windID 第一個窗口ID
    // 獲取對應ID的窗口
    let firstWin = BrowerWindow.fromId(winId)
    firstWin.webContents.send('toIndex', '來自news進程反饋的信息')
    console.log(userInfo)
})

 

3. 在另外一個渲染進程中處理廣播

/* eslint-disable */
let openWindow = document.querySelector('#openWindow');

var { ipcRenderer } = require('electron');

// 渲染進程和渲染進程直接的通訊========
openWindow.onclick = function () {
    // 傳遞消息給主進程
    ipcRenderer.send('openwindow', {name:'poetries', age: 23})

    // 傳遞給打開的窗口 渲染進程和渲染進程直接的通訊
    localStorage.setItem('username', 'poetries')
    
}

// 接收news渲染進程傳遞回來的消息
ipcRenderer.on('toIndex', (e, data)=>{
    console.log('===', data)
})

 

 
image.png

7、Electron Shell 模塊

 
image.png

7.1 Shell 模塊使用

文檔 https://electronjs.org/docs/api/shell

Electron Shell 模塊在用戶默認瀏覽器 中打開 URL 以及 Electron DOM webview 標籤。Shell既屬於主進程模塊又是渲染進程模塊

shell 模塊提供了集成其餘桌面客戶端的關聯功能

1. 引入

<!--index.html-->
<button id="shellDom">經過shell打開外部連接</button>
<script src="render/shell.js"></script>

 

2. shell.js

// src/render/shell.js

const { shell } = require('electron')
let shellDom = document.querySelector('#shellDom');

shellDom.onclick = function (e) {
   shell.openExternal('https://github.com/poetries')
}

 

7.2 Electron DOM <webview> 標籤

Webviewiframe 有點類似,可是與 iframe 不一樣, webview 和你的應用運行的是不一樣的進程。它不擁有渲染進程的權限,而且應用和嵌入內容之間的交互所有都是異步的。由於這能 保證應用的安全性不受嵌入內容的影響。

<!--src/index.html中引入-->
<webview id="webview" src="http://blog.poetries.top" style="position:fixed; width:100%; height:100%">
</webview>

 

7.3 shell模塊<webview>結合Menu模塊使用案例

1. 新建src/render/webview.js

/* eslint-disable */
var { ipcRenderer } = require('electron');
let myWebview = document.querySelector('#myWebview')

ipcRenderer.on('openwebview', (e, url)=>{
    myWebview.src = url
})

 

2. 引入src/index.html

<webview id="myWebview" src="http://blog.poetries.top" style="position:fixed; width:100%; height:100%">
</webview>
    
<script src="render/webview.js"></script>

 

3. 新建src/main/menu.js

/* eslint-disable */
const { shell, Menu, BrowserWindow } = require('electron');

// 當前窗口渲染網頁
function openWebView(url) {
    // 獲取當前窗口Id
    let win = BrowserWindow.getFocusedWindow()

    // 廣播通知渲染進程打開webview
    win.webContents.send('openwebview', url)
}

// 在窗口外打開網頁
function openWeb(url) {
    shell.openExternal(url)
}

let template = [
    {
        label: '幫助',
        submenu: [
            {
                label: '關於咱們',
                click: function () {
                    openWeb('http://blog.poetries.top')
                }
            },
            {
                type: 'separator'
            },
            {
                label: '聯繫咱們',
                click: function () {
                    openWeb('https://github.com/poetries')
                }
            }
        ]
    },
   {
        label: '加載網頁',
        submenu: [
            {
                label: '博客',
                click: function () {
                    openWebView('http://blog.poetries.top')
                }
            },
            {
                type: 'separator' // 分隔符
            },
            {
                label: 'GitHub',
                click: function () {
                    openWebView('https://github.com/poetries')
                }
            },
            {
                type: 'separator' // 分隔符
            },
            {
                label: '簡書',
                click: function () {
                    openWebView('https://www.jianshu.com/users/94077fcddfc0/timeline')
                }
            }
        ]
   },
   {
    label: '視頻網站',
    submenu: [
        {
            label: '優酷',
            click: function () {
                openWebView('https://www.youku.com')
            }
        },
        {
            type: 'separator' // 分隔符
        },
        {
            label: '愛奇藝',
            click: function () {
                openWebView('https://www.iqiyi.com/')
            }
        },
        {
            type: 'separator' // 分隔符
        },
        {
            label: '騰訊視頻',
            click: function () {
                openWebView('https://v.qq.com/')
            }
        }
    ]
    }
]

let m = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(m)

 

4. 引入menu

// 在主進程src/index.js中引入
const createWindow = () => {

  // 建立菜單  
  // 引入菜單模塊
  require('./main/menu.js')
};

 

 
image.png

8、Electron dialog 彈出框

 
image.png

文檔 https://electronjs.org/docs/api/dialog

dialog屬於主進程中的模塊

dialog 模塊提供了 api 來展現原生的系統對話框,例如打開文件框,alert 框, 因此 web 應用能夠給用戶帶來跟系統應用相同的體驗

1. 在src/index.html中引入

<button id="showError">showError</button><br />
<button id="showMsg">showMsg</button><br />
<button id="showOpenDialog">showOpenDialog</button><br />
<button id="saveDialog">saveDialog</button><br />

<script src="render/dialog.js"></script>

 

2. 新建render/dialog.js

// render/dialog.js

let showError = document.querySelector('#showError');
let showMsg = document.querySelector('#showMsg');
let showOpenDialog = document.querySelector('#showOpenDialog');
let saveDialog = document.querySelector('#saveDialog');

var {remote} = require('electron')

showError.onclick = function () {
    remote.dialog.showErrorBox('警告', '操做有誤')
}
showMsg.onclick = function () {
    remote.dialog.showMessageBox({
        type: 'info',
        title: '提示信息',
        message: '內容',
        buttons: ['肯定', '取消']
    },function(index){
        console.log(index)
    })
}
showOpenDialog.onclick = function () {
    remote.dialog.showOpenDialog({
        // 打開文件夾
        properties: ['openDirectory', 'openFile']

        // 打開文件
        // properties: ['openFile']
    }, function (data) {
        console.log(data)
    })
}
saveDialog.onclick = function () {
    remote.dialog.showSaveDialog({
        title: 'Save File',
        defaultPath: '/Users/poetry/Downloads/',
        // filters 指定一個文件類型數組,用於規定用戶可見或可選的特定類型範圍
        filters: [
            { name: 'Images', extensions: ['jpg', 'png', 'gif'] },
            { name: 'Movies', extensions: ['mkv', 'avi', 'mp4'] },
            { name: 'Custom File Type', extensions: ['as'] },
            { name: 'All Files', extensions: ['*'] }
        ]
    }, function (path) {
        // 不是真的保存 ,具體還需nodejs處理
        console.log(path)
    })
}

 

showError

remote.dialog.showErrorBox('警告', '操做有誤') 
 
image.png

showMessageBox

remote.dialog.showMessageBox({
    type: 'info',
    title: '提示信息',
    message: '內容',
    buttons: ['肯定', '取消']
},function(index){
    console.log(index)
})

 

 
image.png

showOpenDialog

remote.dialog.showOpenDialog({
    // 打開文件夾
    properties: ['openDirectory', 'openFile']

    // 打開文件
    // properties: ['openFile']
}, function (data) {
    console.log(data)
})

 

 
image.png

showSaveDialog

remote.dialog.showSaveDialog({
    title: 'Save File',
    defaultPath: '/Users/poetry/Downloads/',
    // filters 指定一個文件類型數組,用於規定用戶可見或可選的特定類型範圍
    filters: [
        { name: 'Images', extensions: ['jpg', 'png', 'gif'] },
        { name: 'Movies', extensions: ['mkv', 'avi', 'mp4'] },
        { name: 'Custom File Type', extensions: ['as'] },
        { name: 'All Files', extensions: ['*'] }
    ]
}, function (path) {
    // 不是真的保存 ,具體還需nodejs處理
    console.log(path)
})

 

 
image.png

9、實現一個相似EditPlus的簡易記事本代碼編輯器

代碼 https://github.com/poetries/electron-demo/tree/master/notepad

10、系統托盤、托盤右鍵菜單、托盤圖標閃爍

 
image.png

文檔 https://electronjs.org/docs/api/tray

系統托盤,托盤右鍵菜單、托盤圖標閃爍 點擊右上角關閉按鈕隱藏到托盤(仿殺毒軟件)

1. 引入文件

// src/index.js
const createWindow = () => {
    require('./main/tray.js')
};

 

2. Electron 建立任務欄圖標以及任務欄圖標右鍵菜單

// src/main/tray.js
var {
    Menu, Tray, app, BrowserWindow
} = require('electron');

const path = require('path');

var appIcon = new Tray(path.join(__dirname, '../static/lover.png'));

const menu = Menu.buildFromTemplate([
    {
        label: '設置',
        click: function() {} //打開相應頁面 
    },
    {
        label: '幫助',
        click: function() {}
    },
    {
        label: '關於',
        click: function() {}
    },
    {
        label: '退出',
        click: function() { 
            // BrowserWindow.getFocusedWindow().webContents().send('close-main-window');
            app.quit();
    }
}])
// 鼠標放上去提示信息
appIcon.setToolTip('hello poetries');
appIcon.setContextMenu(menu);

 

 
mac系統托盤

3. 監放任務欄圖標的單擊、雙擊事件

// 實現點擊關閉按鈕,讓應用保存在托盤裏面,雙擊托盤打開
let win = BrowserWindow.getFocusedWindow()

win.on('close', (e)=>{
    e.preventDefault()
    win.hide()
})

iconTray.on('double-click', (e)=>{
    win.show()
})

 

4. Electron 點擊右上角關閉按鈕隱藏任務欄圖標

const win = BrowserWindow.getFocusedWindow();

win.on('close', (e) =>{

    console.log(win.isFocused());
    
    if (!win.isFocused()) {
        win = null;
    } else {
        e.preventDefault();/*阻止應用退出*/
        win.hide();/*隱藏當前窗口*/
    }
})

 

5. Electron 實現任務欄閃爍圖標

var appIcon = new Tray(path.join(__dirname, '../static/lover.png'));

timer = setInterval(function() {
    count++;
    if (count % 2 == 0) {
        appIcon.setImage(path.join(__dirname, '../static/empty.ico'))
    } else {
        appIcon.setImage(path.join(__dirname, '../static/lover.png'))
    }
},
500);

 

11、消息通知、監聽網絡變 化、網絡變化彈出通知框

11.1 消息通知

1. Electron 實現消息通知

Electron 裏面的消息通知是基於 h5 的通知 api 實現的

文檔 https://developer.mozilla.org/zh-CN/docs/Web/API/notification

1. 新建notification.js

// h5api實現通知
const path = require('path')

let options = {
    title: 'electron 通知API',
    body: 'hello poetries',
    icon: path.join('../static/img/favicon2.ico') // 通知圖標
}


document.querySelector('#showNotification').onclick = function () {
    let myNotification  = new window.Notification(options.title, options)
    
    // 消息可點擊
    myNotification.onclick = function () {
        console.log('click notification')
    }
}

 

2. 引入

<!--src/index.html-->

<button id="showNotification">彈出消息通知</button>
<script src="render/notification.js"></script>

 

mac上的消息通知

 
mac上的消息通知

11.2 監聽網絡變化

1. 基本使用

 // 監聽網絡變化
// 端開網絡 再次鏈接測試
 window.addEventListener('online', function(){
    console.log('online')
 }); 
 
 window.addEventListener('offline', function(){
    console.log('offline')
 });

 

2. 監聽網絡變化實現消息通知

// 端開網絡 再次鏈接測試
// 監聽網絡變化實現消息通知
window.addEventListener('online', function(){
   console.log('online')
}); 
window.addEventListener('offline', function(){
   // 斷開網絡觸發事件
   var options = {
       title: 'QQ郵箱',
       body: '網絡異常,請檢查你的網絡',
       icon: path.join('../static/img/favicon2.ico') // 通知圖標
   }
   var myNotification  = new window.Notification(options.title, options)
   myNotification.onclick = function () {
       console.log('click notification')
   }
});

 

 
image.png

12、註冊全局快捷鍵/剪切板事件/nativeImage 模塊

Electron 註冊全局快捷鍵 (globalShortcut) 以及 clipboard 剪 切板事件以及 nativeImage 模塊(實現相似播放器點擊機器碼自動複製功 能)

12.1 註冊全局快捷鍵

 
image.png

1. 新建src/main/shortCut.js

const {globalShortcut, app} = require('electron')

app.on('ready', ()=>{
    // 註冊全局快捷鍵
    globalShortcut.register('command+e', ()=>{
        console.log(1)
    })

    // 檢測快捷鍵是否註冊成功 true是註冊成功
    let isRegister = globalShortcut.isRegistered('command+e')
    console.log(isRegister)
})

// 退出的時候取消全局快捷鍵
app.on('will-quit', ()=>{
    globalShortcut.unregister('command+e')
})

 

2. 引入src/index.js

// 注意在外部引入便可 不用放到app中
require('./main/shortCut.js')

 

12.2 剪切板clipboard、nativeImage 模塊

 
image.png

1. html

<!--src/index.html-->
<div>
  <h2>雙擊下面信息複製</h2>
  <p id='msg'>123456789</p>
  <button id="plat">粘貼</button><br />
  <input id="text" type="text"/>
</div>.
<div>
  <h2>複製圖片到界面</h2>
  <button id="copyImg">複製圖片</button><br />
</div>
<script src="render/clipboard.js"></script>

 

2. 新建src/render/clipboard.js

// clipboard能夠在主進程或渲染進程使用
const { clipboard, nativeImage }  = require('electron')

//複製
// 運行ctrl+v可看到複製的內容
// clipboard.writeText('poetries')

// clipboard.readText() //獲取複製的內容 粘貼

// 雙擊複製消息
let msg = document.querySelector('#msg')
let plat = document.querySelector('#plat')
let text = document.querySelector('#text')

msg.ondblclick  = function () {
    clipboard.writeText(msg.innerHTML)
    alert(msg.innerHTML)
}
plat.onclick = function () {
    text.value = clipboard.readText()
}

// 複製圖片顯示到界面
let copyImg = document.querySelector('#copyImg')
copyImg.onclick = function () {
    // 結合nativeImage模塊
    let image = nativeImage.createFromPath('../static/img/lover.png') 

    // 複製圖片
    clipboard.writeImage(image)

    // 粘貼圖片
    let imgSrc = clipboard.readImage().toDataURL() // base64圖片

    // 顯示到頁面上
    let imgDom = new Image()
    imgDom.src = imgSrc 
    document.body.appendChild(imgDom)
}

 

十3、結合electron-vue

13.1 electron-vue 的使用

1. electron-vue 的一些資源

https://github.com/SimulatedGREG/electron-vue

Electron-vue 文檔 https://simulatedgreg.gitbooks.io/electron-vue/content/cn

2. electron-vue 環境搭建、建立項目

npm install -g vue-cli

vue init simulatedgreg/electron-vue my-project

cd my-project

yarn # or npm install

yarn run dev # or npm run dev

 

3. electron-vue 目錄結構分析

 
image.png

13.2 electron-vue 中使用 sass/ElementUi

1. electron-vue UI 框架 ElementUi 的使用

http://element-cn.eleme.io/#/zh-CN

2. electron-vue 中使用 sass

# 安裝 sass-loader:

npm install --save-dev sass-loader node-sass
<!--vue 文件中修改 style 爲以下代碼:-->

<style lang="scss"> 
    body {
        /* SCSS */ 
    }
</style>

 

13.3 electron-vue 中隱藏頂部菜單隱藏

electron-vue 中隱藏頂部菜單隱藏頂部最大化、最小化、關閉按鈕 自定最大化、最小化 、關閉按鈕

1. electron-vue 中隱藏頂部菜單

// src/main/index.js mainWindow.setMenu(null) 

2. electron-vue 中隱藏關閉 最大化 最小化按鈕

// src/main/index.js
mainWindow = new BrowserWindow({
    height: 620,
    useContentSize: true,
    width: 1280,
    frame: false /*去掉頂部導航 去掉關閉按鈕 最大化最小化按鈕*/
})

 

3 .electron-vue 自定義關閉/最大化最小化按鈕

// 注意在mac下不須要監聽窗口最大最小化、覺得系統默認支持,這個只是針對windows平臺

ipc.on('window-min',function() {
    mainWindow.minimize();
})

//登陸窗口最大化 
ipc.on('window-max',function(){
    if (mainWindow.isMaximized()) {
        mainWindow.restore();
    } else {
        mainWindow.maximize();
    }
}) 

ipc.on('window-close',function() {
    mainWindow.close();
})

 

4. electron-vue 自定義導航可拖拽

  • 可拖拽的 css: -webkit-app-region: drag;
  • 不可拖拽的 css: -webkit-app-region: no-drag;

13.4 使用electron-vue開發輿情監控系統

13.4.1 配置開發環境

1. 項目搭建

npm install -g vue-cli

vue init simulatedgreg/electron-vue my-project

cd my-project

yarn # or npm install

yarn run dev # or npm run dev

 

2. 安裝一些依賴

# 安裝 sass-loader:
npm install --save-dev sass-loader node-sass

# 安裝elementUI、js-md5
npm i element-ui  js-md5 -S
在.electron-vue/webpack.renderer.config.js中配置sass-loader就能夠編寫``sass`了
<!--vue 文件中修改 style 爲以下代碼:-->

<style lang="scss"> 
    body {
        /* SCSS */ 
    }
</style>

 

13.4.2 主進程配置

1. src/main/index.js

function createWindow () {
  // 去掉頂部菜單
  mainWindow.setMenu(null)
  
  // 菜單項
  require('./model/menu.js');
  
  // 系統托盤相關
  require('./model/tray.js');

 

2. src/main/menu.js菜單配置

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


//右鍵菜單
const contextMenuTemplate=[
    {
        label: '複製', role: 'copy' },
    {
        label: '黏貼', role: 'paste' },        
    { type: 'separator' }, //分隔線
    {
        label: '其餘功能',     
        click: () => {
        console.log('click')
         }
    }
];

const contextMenu=Menu.buildFromTemplate(contextMenuTemplate);


ipcMain.on('contextmenu',function(){

    contextMenu.popup(BrowserWindow.getFocusedWindow());

})

 

3. src/main/tray.js系統托盤配置

托盤點擊監聽事件只有在windows下才生效,mac系統默認支持

(function () {
    const path=require('path');
    const {app,Menu,BrowserWindow,Tray, shell} = require('electron');

    //建立系統托盤
    const tray = new Tray(path.resolve(__static, 'favicon.png'))

    //給托盤增長右鍵菜單
    const template= [
        {
            label: '設置',
            click: function () {
                shell.openExternal('http://blog.poetries.top')
            }
        },
        {
            label: '幫助',
            click: function () {
                shell.openExternal('http://blog.poetries.top/2019/01/06/electron-summary')
            }
        },
        {
            label: '關於',
            click: function () {
                shell.openExternal('https://github.com/poetries/yuqing-monitor-electron')
            }
        },
        {
            label: '退出',
            click: function () {
                // BrowserWindow.getFocusedWindow().webContents().send('close-main-window');
                app.quit();
            
            }
        }
    ];

    const menu = Menu.buildFromTemplate(template);
    tray.setContextMenu(menu);


    tray.setToolTip('輿情監控系統');


    //監聽關閉事件隱藏到系統托盤
    // 這裏須要注意:在window中才生效,mac下系統默認支持
    // var win = BrowserWindow.getFocusedWindow();
    // win.on('close',(e)=>{
    //         if(!win.isFocused()){
    //             win=null;
    //         }else{
    //             e.preventDefault();  /*阻止應用退出*/

    //             win.hide(); /*隱藏當前窗口*/

    //         }       
    // })

    // //監聽托盤的雙擊事件
    // tray.on('double-click',()=>{               
    //     win.show();
    // })
})()

 

4. src/main/shortCut.js快捷鍵配置

src/main/index.js中引入(require('src/main/shortCut.js'))便可,不須要放到app監控中

var {globalShortcut, app} = require('electron')

app.on('ready', ()=>{
    // 註冊全局快捷鍵
    globalShortcut.register('command+e', ()=>{
        console.log(1)
    })

    // 檢測快捷鍵是否註冊成功 true是註冊成功
    let isRegister = globalShortcut.isRegistered('command+e')
    console.log(isRegister)
})

// 退出的時候取消全局快捷鍵
app.on('will-quit', ()=>{
    globalShortcut.unregister('command+e')
})

 

13.4.3 渲染進程配置

1. src/render/main.js配置

import Vue from 'vue'
import axios from 'axios'

import App from './App'
import router from './router'
import store from './store'

import ElementUI from 'element-ui';
import 'element-ui/lib/theme-chalk/index.css';
import VueHighcharts from 'vue-highcharts';
import VueSocketIO from 'vue-socket.io'

Vue.use(ElementUI);
Vue.use(VueHighcharts);

//引入socket.io配置鏈接
Vue.use(new VueSocketIO({
  debug: true,
  connection: 'http://118.123.14.36:3000',
  vuex: {
      store,
      actionPrefix: 'SOCKET_',
      mutationPrefix: 'SOCKET_'
  }
}))

if (!process.env.IS_WEB) Vue.use(require('vue-electron'))
Vue.http = Vue.prototype.$http = axios
Vue.config.productionTip = false


/* eslint-disable no-new */
new Vue({
  components: { App },
  router,
  store,
  template: '<App/>'
}).$mount('#app')

 

2. 路由配置src/renderer/router/index.js

import Vue from 'vue'
import Router from 'vue-router'

Vue.use(Router)

export default new Router({
  routes: [
    {
      path: '/home',
      name: 'home',
      component: require('@/components/Home').default
    },
    {
      path: '/report',
      name: 'report',
      component: require('@/components/Report').default
    },
    {
      path: '/negativereport',
      name: 'negativereport',
      component: require('@/components/NegativeReport').default
    },
    {
      path: '/positivereport',
      name: 'positivereport',
      component: require('@/components/PositiveReport').default
    },
    {
      path: '/keyword',
      name: 'keyword',
      component: require('@/components/KeyWord').default
    },
    {
      path: '/alarm',
      name: 'alarm',
      component: require('@/components/Alarm').default
    },
    {
      path: '/msg',
      name: 'msg',
      component: require('@/components/Msg').default
    },
    {
      path: '*',
      redirect: '/home'
    }
  ]
})

 

其餘頁面更多詳情Github

3. 在渲染進程中使用主進程方式

// electron掛載到了vue實例上 $electron
this.$electron.shell

 

13.4.4 多平臺打包

須要注意的是打包mac版本在mac系統上打包,打包window則在windows上打包,能夠避免不少問題

# 在不一樣平臺上執行便可打包應用
npm run build

 

13.4.4.1 打包介紹

electron-vue打包文檔

1. electron 中構建應用最經常使用的模塊

  • electron-packager
  • electron-builder

electron-packagerelectron-builder在本身單首創建的應用用也能夠完成打包功 能。可是因爲配置太複雜因此咱們不建議單獨配置

2. electron-forge

https://github.com/electron-userland/electron-forge

electron-forge package electron-forge make 

3. electron-vue中的打包方式

# https://simulatedgreg.gitbooks.io/electron-vue/content/cn/using-electron-packager. html
# 之須要執行一條命令
npm run build

13.4.4.2 修改應用信息

1. 修改package.json

 
image.png

2. 修改src/index.ejs標題信息

3. 修改build/icons圖標

13.4.4.3 打包遇到的問題

1. 建立應用托盤的時候可能會遇到錯誤

  • 把托盤圖片放在根目錄static裏面,而後注意下面寫法。
var tray = new Tray(path.join(__static,'favicon.ico')) 
  • 若是托盤路徑沒有問題,仍是包托盤相關錯誤的話,把托盤對應的圖片換成.png 格式重試

2. 模塊問題可能會遇到的錯誤

 
image.png
 
image.png

解決辦法

  • 刪掉 node_modules 而後從新用 npm install 安裝依賴
  • yarn 來安裝模塊
  • 用手機建立一個熱點電腦連上熱點重試

最後執行yarn run build便可

 
項目打包結果

項目截圖

輿情監控系統頁面

 
登陸頁
 
首頁
 
所有輿情
 
輿情關鍵詞
 
增長關鍵詞
 
輿情報警設置

系統系統托盤、electron 消息通知 (相似騰訊新聞)

 
系統托盤
 
消息通知

項目源碼 https://github.com/poetries/yuqing-monitor-electron

十4、更多參考

 

做者:poetries連接:https://www.jianshu.com/p/2244653515a7來源:簡書著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

相關文章
相關標籤/搜索