electron組成
electron由Node.js+Chromium+Native APIs構(gòu)成孵淘〈趼ǎ可以理解為,它是一個(gè)得到了Node.js和基于不同平臺(tái)的Native APIs加強(qiáng)的Chromium瀏覽器背捌,可以用來開發(fā)跨平臺(tái)的桌面級(jí)應(yīng)用洞斯。
主進(jìn)程(mian process)
主進(jìn)程,通常是值 main.js 文件么抗,是每個(gè) Electron 應(yīng)用的入口文件亚铁。它控制著整個(gè) App 的生命周期,從打開到關(guān)閉徘溢。 它也管理著原生元素比如菜單然爆,菜單欄,Dock 欄施蜜,托盤等。 主進(jìn)程負(fù)責(zé)創(chuàng)建 APP 的每個(gè)渲染進(jìn)程缸沃。而且整個(gè) Node API 都集成在里面。
每個(gè) app 的主進(jìn)程文件都定義在 package.json 中的 main 屬性當(dāng)中
在Chromium中, 這個(gè)進(jìn)程被稱為 "瀏覽器進(jìn)程"检盼。它在Electron被重新命名, 以避免與渲染器進(jìn)程混淆翘单。
渲染進(jìn)程(renderer process)
渲染進(jìn)程是應(yīng)用內(nèi)的一個(gè)瀏覽器窗口。與主進(jìn)程不同的是哄芜,它能夠同時(shí)存在多個(gè)而且運(yùn)行在不一樣的進(jìn)程认臊。而且它們也能夠被隱藏。
在通常的瀏覽器內(nèi)失晴,網(wǎng)頁通常運(yùn)行在一個(gè)沙盒的環(huán)境擋住并且不能夠使用原生的資源。 然而 Electron 的用戶在 Node.js 的 API 支持下可以在頁面中和操作系統(tǒng)進(jìn)行一些低級(jí)別的交互书在。
項(xiàng)目工程(electron-vue)
?? 模版
vue init simulatedgreg/electron-vue my-project
?? app
生命周期鉤子
will-finish-launching 在應(yīng)用完成基本啟動(dòng)進(jìn)程之后觸發(fā)
ready 當(dāng)electron完成初始化后觸發(fā)
window-all-closed 所有窗口都關(guān)閉的時(shí)候觸發(fā)儒旬,在windows和linux里遏乔,所有窗口都退出的時(shí)候通常是應(yīng)用退出的時(shí)候
before-quit 退出應(yīng)用之前的時(shí)候觸發(fā)
will-quit 即將退出應(yīng)用的時(shí)候觸發(fā)
quit 應(yīng)用退出的時(shí)候觸發(fā)
事件鉤子
active(僅macOS)當(dāng)應(yīng)用處于激活狀態(tài)時(shí)
browser-window-created 當(dāng)一個(gè)BrowserWindow被創(chuàng)建的時(shí)候
browser-window-focus 當(dāng)一個(gè)BrowserWindow處于激活狀態(tài)的時(shí)候
...
?? BrowserWindow
創(chuàng)建窗口
new BrowserWindow([options])
//options除了可以設(shè)置窗口樣式及功能发笔,還涉及網(wǎng)頁功能設(shè)置
事件鉤子
closed 當(dāng)窗口被關(guān)閉的時(shí)候
focus 當(dāng)窗口被激活的時(shí)候
show 當(dāng)窗口展示的時(shí)候
...
?? 主進(jìn)程和renderer進(jìn)程的通信
ipcMain模塊是EventEmitter類的一個(gè)實(shí)例了讨。 在主進(jìn)程使用時(shí),它處理異步并且接收來自于渲染進(jìn)程(網(wǎng)頁)的同步信息前计。 從渲染器進(jìn)程發(fā)送的消息將被發(fā)送到該模塊。
回復(fù)同步信息時(shí)丈屹,需要設(shè)置event.returnValue。
將異步消息發(fā)送回發(fā)件人彩库,需要使用event.sender.send(...)先蒋。
方法:
ipcMain.on(channel, listener)
ipcMain.once(channel, listener)
ipcMain.removeListener(channel, listener)
ipcMain.removeAllListeners([channel])
ipcRenderer 是一個(gè) EventEmitter 的實(shí)例。 你可以使用它提供的一些方法從渲染進(jìn)程 (web 頁面) 發(fā)送同步或異步的消息到主進(jìn)程竞漾。 也可以接收主進(jìn)程回復(fù)的消息业岁。
方法:
ipcRenderer.on(channel, listener)
ipcRenderer.once(channel, listener)
ipcRenderer.removeListener(channel, listener)
ipcRenderer.removeAllListeners([channel])
ipcRenderer.send(channel[, arg1][, arg2][, ...])
ipcRenderer.sendSync(channel[, arg1][, arg2][, ...])
ipcRenderer.sendToHost(channel[, arg1][, arg2][, ...])
在渲染進(jìn)程中使用node
import os from 'os'
import fs from 'fs'
import async from 'async'
import path from 'path'
inspectAndDescribeFile(filePath, cb) {
let result = {
file: path.basename(filePath),
path: filePath,
type: ''
}
fs.stat(filePath, (err, stat) => {
if(err) {
cb(err)
}else{
if(stat.isFile()) {
result.type = 'file'
}
if(stat.isDirectory()) {
result.type = 'directory'
}
cb(err, result)
}
})
},
?? 調(diào)試
1.渲染進(jìn)程調(diào)試
chrome devtools
-
devtron:
npm install devtron --save-dev
在console中執(zhí)行: require('devtron').install()
2.主進(jìn)程調(diào)試
VS Code
?? 打包
electron-builder OR electron-packager
builder 是在 packager 基礎(chǔ)上的整合版,提供開發(fā)到部署一整套繁扎,生產(chǎn)各個(gè)平臺(tái)可以執(zhí)行文件糊闽、安裝程序、軟件簽名提澎、自動(dòng)更新念链。
使用electron-builder 打包
npm run build
跨平臺(tái)打包:
/*package.json*/
//打包mac
node .electron-vue/build.js && electron-builder --mac
//打包win
node .electron-vue/build.js && electron-builder --win
//打包linux
node .electron-vue/build.js && electron-builder --linux
//全部打包
node .electron-vue/build.js && electron-builder --platform=all
?? 項(xiàng)目遷移
- 將原有項(xiàng)目src文件夾下的文件遷移至renderer目錄下
?? 注意事項(xiàng)
注意拖拽事件
路由使用hash模式 (electron在生產(chǎn)環(huán)境下使用的是file://協(xié)議)
-
跨域問題:
mainWindow = new BrowserWindow({ webPreferences: {webSecurity: false}, }) allowRunningInsecureContent Boolean //(可選) -允許一個(gè) https 頁面運(yùn)行 http url 里的資源,包括 JavaScript, CSS 或 plugins. 默認(rèn)值為 false.
跨平臺(tái)兼容
原生相關(guān)
托盤
Tray
let tray = new Tray(`${__static}/menubar.png`)
const contextMenu = Menu.buildFromTemplate([
{label: 'Item1', type: 'radio', click() {dialog.showMessageBox({title: 'click', message: 'click the item', detail: 'The item has been clicked!'})}},
{label: 'Item2', type: 'radio'},
{label: 'Item3', type: 'radio', checked: true},
{label: 'Item4', type: 'radio'}
])
tray.setToolTip('This is an application.')
tray.setContextMenu(contextMenu)
應(yīng)用菜單
Menu
MenuItem
let template = [
{label: 'item0', submenu: [{label: 'item0-0'}, {label: 'item0-1'}]},
{label: 'item1', submenu: [{label: 'item1-0'}, {label: 'item1-1'}]},
{label: 'item2', submenu: [{label: 'item2-0'}, {label: 'item2-1'}]},
{label: 'item3', submenu: [{label: 'item3-0'}, {label: 'item3-1'}]},
{label: 'item4', submenu: [{label: 'item4-0'}, {label: 'item4-1'}]}
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
桌面通知
electron-notification