Electron 實戰桌面計算器應用

来源:http://www.cnblogs.com/linxin/archive/2017/09/04/7472115.html
-Advertisement-
Play Games

前言 Electron 是一個搭建跨平臺桌面應用的框架,僅僅使用 JavaScript、HTML 以及 CSS,即可快速而容易地搭建一個原生應用。這對於想要涉及其他領域的開發者來說是一個非常大的福利。 原文作者:林鑫,作者博客:http://blog.gdfengshuo.com/ 項目介紹 倉庫地 ...


前言

Electron 是一個搭建跨平臺桌面應用的框架,僅僅使用 JavaScript、HTML 以及 CSS,即可快速而容易地搭建一個原生應用。這對於想要涉及其他領域的開發者來說是一個非常大的福利。

原文作者:林鑫,作者博客:http://blog.gdfengshuo.com/

項目介紹

倉庫地址:lin-xin/calculator

我這裡通過 Electron 實現了仿 iPhone 的計算器,通過菜單可以切換橫屏和豎屏,橫屏有更多的運算。而對於 JavaScript 進行浮點數計算來說,精度丟失是個很大問題,所以我這裡使用了第三方庫 math.js 來解決這個精度的問題。
儘可能的實現了跟 iPhone 一樣的運算:

  • 1 + 2 × 3 = 7
  • 3 += 6 (再按 = 等於 9)
  • 0.1 + 0.2 = 0.3 (浮點數精度處理)

Image text
Image text

不過我下麵並不是要講計算器,而是用到的 Electron 的知識點。

生命周期

在主進程中通過 app 模塊控制整個應用的生命周期。

當 Electron 完成初始化時觸發 ready 事件:

app.on('ready', () => {
    // 創建視窗、載入頁面等操作
})

當所有的視窗都被關閉時會觸發 window-all-closed 事件:

app.on('window-all-closed', () => {
    if(process.platform !== 'darwin'){
        app.quit();     // 退出應用
    }
})

在開發中發現,沒有監聽該事件,打包後的應用關閉後,進程還保留著,會占用系統的記憶體。

視窗

本來我們的 html 只顯示在瀏覽器中,而 electron 提供了一個 BrowserWindow 模塊用於創建和控制瀏覽器視窗,我們的頁面就是顯示在這樣的視窗中。

創建視窗

通過關鍵字 new 實例化返回 win 對象,該對象有豐富的方法對視窗進行控制。

win = new BrowserWindow({
    width: 390,         // 視窗寬度
    height: 670,        // 視窗高度
    fullscreen: false,  // 不允許全屏
    resizable: false    // 不允許改變視窗size,不然佈局就亂了啊
});

載入頁面

視窗創建完是一片空白的,可以通過 win.loadURL() 來載入要顯示的頁面。

const path = require('path');
const url = require('url');

win.loadURL(url.format({    // 載入本地的文件
    pathname: path.join(__dirname, 'index.html'),
    protocol: 'file',
    slashes: true
}))

也可以直接載入遠程鏈接 win.loadURL('http://blog.gdfengshuo.com');

菜單

桌面應用菜單欄是最常見的功能。Electron 提供了 Menu 模塊來創建原生的應用菜單和 context 菜單,

const template = [                              // 創建菜單模板
    {
        label: '查看',
        submenu: [
            {label: '豎屏', type: 'radio', checked: true},      // type 屬性讓菜單為 radio 可選
            {label: '橫屏', type: 'radio', checked: false},
            {label: '重載',role:'reload'},
            {label: '退出',role:'quit'},
        ]
    }
]

const menu = Menu.buildFromTemplate(template);  // 通過模板返回菜單的數組
Menu.setApplicationMenu(menu);                  // 將該數組設置為菜單

在子菜單中,通過點擊豎屏或橫屏來進行一些操作,那就可以給 submenu 監聽 click 事件。

const template = [
    {
        label: '查看',
        submenu: [
            {
                label: '橫屏'
                click: () => {              // 監聽橫屏的點擊事件
                    win.setSize(670,460);   // 設置視窗的寬高
                }
            }
        ]
    }
]

主進程和渲染進程通信

雖然點擊橫屏的時候,可以設置視窗的寬高,但是要如何去觸發頁面里的方法,這裡就需要主進程跟渲染進程之間進行通信。

主進程,可以理解為 main.js 用來寫 electron api 的就是主進程,渲染進程就是渲染出來的頁面。

ipcMain

在主進程中可以使用 ipcMain 模塊,它控制著由渲染進程(web page)發送過來的非同步或同步消息。

const {ipcMain} = require('electron')
ipcMain.on('send-message', (event, arg) => {
    event.sender.send('reply-message', 'hello world')
})

ipcMain 監聽 send-message 事件,當消息到達時可以調用 event.sender.send 來回覆非同步消息,向渲染進程發送 reply-message 事件,也可以帶著參數發送過去。

ipcRenderer

在渲染進程可以調用 ipcRenderer 模塊向主進程發送同步或非同步消息,也可以收到主進程的相應。

const {ipcRenderer} = require('electron')
ipcRenderer.on('reply-message', (event, arg) => {
    console.log(arg);       // hello world
})

ipcRenderer.send('anything', 'hello everyone');

ipcRenderer 可以監聽到來自主進程的 reply-message 事件並拿到參數進行操作,也可以使用 send() 方法向主進程發送消息。

webContents

webContents 是一個事件發出者,它負責渲染並控制網頁,也是 BrowserWindow 對象的屬性。在 ipcMain 中的 event.sender,返回發送消息的 webContents 對象,所以包含著 send() 方法用於發送消息。

const win = BrowserWindow.fromId(1);        // fromId() 方法找到ID為1的視窗
win.webContents.on('todo', () => {
    win.webContents.send('done', 'well done!')
})

remote

remote 模塊提供了一種在渲染進程(網頁)和主進程之間進行進程間通訊(IPC)的簡便途徑。在 Electron 中,有許多模塊只存在主進程中,想要調用這些模塊的方法需要通過 ipc 模塊向主進程發送消息,讓主進程調用這些方法。而使用 remote 模塊,則可以在渲染進程中調用這些只存在於主進程對象的方法了。

const {remote} = require('electron')
const BrowserWindow = remote.BrowserWindow      // 訪問主進程中的BrowserWindow模塊

let win = new BrowserWindow();                  // 其他的跟主進程的操作都一樣

remote 模塊除了可以訪問主進程的內置模塊,自身還有一些方法。

remote.require(module)          // 返回在主進程中執行 require(module) 所返回的對象
remote.getCurrentWindow()       // 返回該網頁所屬的 BrowserWindow 對象
remote.getCurrentWebContents()  // 返回該網頁的 WebContents 對象
remote.getGlobal(name)          // 返回在主進程中名為 name 的全局變數(即 global[name])
remote.process                  // 返回主進程中的 process 對象,等同於 remote.getGlobal('process') 但是有緩存

shell 模塊

使用系統預設應用管理文件和 URL,而且在主進程和渲染進程中都可以用到該模塊。在菜單中,我想點擊子菜單打開一個網站,那麼就可以用到 shell.openExternal() 方法,則會在預設瀏覽器中打開 URL

const {shell} = require('electron');
shell.openExternal('https://github.com/lin-xin/calculator');

打包應用

其實將程式打包成桌面應用才是比較麻煩的事。我這裡嘗試了 electron-packager 和 electron-builder。

electron-packager

electron-packager 可以將項目打包成各平臺可直接運行的程式,而不是安裝包。

先使用 npm 安裝: npm install electron-packager -S

運行打包命令:

electron-packager ./ 計算器 --platform=win32 --overwrite --icon=./icon.ico

打包會把項目文件包括 node_modules 也一起打包進去,當然可以通過 --ignore=node_modules 來忽略文件,但是如果項目中有用到第三方庫,忽略的話則找不到文件報錯了。

正確的做法就是嚴格區分 dependencies 和 devDependencies,打包的時候只會把 dependencies 的庫打包,而使用 cnpm 安裝的會有一大堆 .0.xx@xxx 的文件,也會被打包,所以最好不要用 cnpm

electron-builder

electron-builder 是基於 electron-packager 打包出來的程式再做安裝處理,將項目打包成安裝文件。

安裝:npm install electron-builder -S

打包:electron-builder --win

打包過程中,第一次下載 electron 可能會出現連接超時,可以使用 yarn 試試。還有 winCodeSign 和 nsis-resources 也可能會失敗,可以參考 electron-builder/issues 解決。

總結

Electron 用起來還是相對容易的,可以創建個簡單的桌面應用,只是打包的過程比較容易遇到問題,網上好像也有一鍵打包的工具,沒嘗試過。以上也都是基於 windows 7 的實踐,畢竟沒有 Mac 搞不了。

更多文章:linxin/blog


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 源碼 https://github.com/2016Messi/Gorgeous clock 效果展示 https://2016messi.github.io/Gorgeous clock/ 如果各位博友覺得效果不錯,歡迎star ...
  • 用純js畫一棵樹。思路: 1、一棵樹的圖片,作為頁面背景; 2、通過html5中的canvas畫布進行遮罩; 3、定時每隔10ms,從下往上清除1px的遮罩; 畫的過程如下: ...
  • 數組常用方法總結: 下麵我只總結了es3中常用的數組方法,一共有11個。es5中新增的9個數組方法,後續再單獨總結。 1個連接數組的方法:concat() 2個數組轉換為字元串的方法:join()、toString() 6個增刪數組元素的方法:pop()、push()、shift()、unshift ...
  • 一、增加 1.push() 語法:arrayObject.push(newele1,newele2,…,neweleX); 功能:將push中的參數添加到arrayObject的尾部 返回值:把指定的值添加到數組後的新長度 例: var arr = [8,7,5,2,8,4,3]; var arrL ...
  • 裡面封裝了很多組件、字體圖標、和標簽常用的一些樣式。我們直接使用即可。 下載地址: http://www.bootcss.com/ 包下載地址(用於生產環境的 Bootstrap):https://github.com/twbs/bootstrap/releases/download/v3.3.7/ ...
  • AJAX跨域的問題很常見,有較多的解決辦法如:jsonp,設置服務端允許跨域,給請求加代理等等解決方式,我項目中常用node.js搭建中間代理的方式解決。下麵我將嘗試採用nginx做代理的方式解決跨域的問題。第一步:搭建Server API,其中未設置允許跨域。get方法,返回英雄列表。(http:... ...
  • 1. 什麼是CSS CSS的全稱是Cascading Style Sheets,層疊樣式表。它用來控制HTML標簽的樣式,在美化網頁中起到非常重要的作用。 CSS的編寫格式是鍵值對形式的,比如 color: red; background-color: blue; font-size: 20px; ...
  • 1. 什麼是HTML5 網頁的5.0版本。2014年才定製完HTML5的標準,歷時8年 2. 為什麼要用HTML5 1> 跨平臺:利用HTML5編寫的UI界面能運行在所有擁有瀏覽器的平臺 2> HTML5的運行平臺:瀏覽器 3> 但是HTML5不能完成一些特定的功能,比如:拍照(ImagePicke ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...