-
技术架构
- Chromium - Chrome浏览器内核
- Node.js
- Native apis - 系统api
-
生命周期事件
- ready:app初始化完成
- dom-ready:一个窗口中的文本加载完成
- did-finish-load:导航完成时触发
- window-all-closed:所有窗口都被关闭时触发(如果监听了该事件需要手动调用app.quit()方法才可以关闭app)
- before-quit:在关闭窗口之前触发
- will-quit:在窗口关闭并且应用退出时触发
- quit:当所有窗口被关闭时触发
- closed:当窗口关闭时触发,此时应删除窗口引用
-
使用nodemon命令可以实现监听和动态刷新
"scripts": {
"start": "nodemon --watch main.js --exec npm run build",
"build": "electron ."
},
- 通过配置BrowserWindow的show属性可以解决页面白屏问题
const mainWindow = new BrowserWindow({
show: false,
width: 800,
heigh: 400
})
mainWindow.on('ready-to-show', () => {
mainWindow.show()
})
- 窗口属性
- resizable:是否允许拉伸窗口
- minHeight/Width:最小高度/宽度
- maxHeight/Width:最大高度/宽度
- title:窗口标题
- icon:窗口图标
- frame:是否包含窗体操作栏
- reansparent:透明窗体
- autoHideMenuBar:是否隐藏菜单栏
electron12.0.0版本废弃了remote,需要使用@electron/remote进行替代
- 设置以下属性可以让渲染进程也可以使用require
// BrowserWindow配置
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
enableRemoteModule: true
}
-
渲染进程使用electron相关的API,必须使用remote获取:
-
在
主进程中初始化并开启模块,其中mainWindow为主窗口实例
require('@electron/remote/main').initialize()
require("@electron/remote/main").enable(mainWindow.webContents)
- 在
渲染进程中引入
const {BrowserWindow}=require('@electron/remote')
- 使用remote可以获取当前窗口
const { BrowserWindow, getCurrentWindow } = require('@electron/remote')
getCurrentWindow()
- 可以使用Menu来实现自定义菜单
const { Menu } = require('electron')
const template = [
{label: 'file',
icon: './xx.png' // 定制菜单图标
accelerator: 'ctrl + o', // 定义快捷键
click() {
... // 定义点击菜单的处理事件
}
},
...
]
const menu = Menu.buildFromTemplate(template)
Menu.setApplicationMenu(menu)
- 打开外部链接
const { shell } = require('electron')
await shell.openExternal('https://electronjs.org')
- 获取当前运行系统平台的类型
const isMac = process.platform === 'darwin' // 是否为Mac系统
- 实现右键点击菜单
// renderer
window.addEventListener('contextmenu', (e) => {
e.preventDefault()
ipcRenderer.send('show-context-menu')
})
ipcRenderer.on('context-menu-command', (e, command) => {
// ...
})
// main
ipcMain.on('show-context-menu', (event) => {
const template = [
{
label: 'Menu Item 1',
click: () => { event.sender.send('context-menu-command', 'menu-item-1') }
},
{ type: 'separator' },
{ label: 'Menu Item 2', type: 'checkbox', checked: true }
]
const menu = Menu.buildFromTemplate(template)
menu.popup({ window: BrowserWindow.fromWebContents(event.sender) }) // 在当面窗口弹出菜单
})
-
主进程和渲染进程间的通信
-
渲染进程向主进程发送消息
const { ipcRenderer } = require('electron') // 必须引入的模块
// 渲染进程
ipcRenderer.send('xtom', "一条来自渲染进程的消息!")
const returnValue = ipcRenderer.sendSync('xtoms', "一条来自渲染进程的同步消息!")
// 主进程
ipcMain.on('xtom', (ev, data) => {
ev.sender.send('xtomRe', '一条来自主进程的回复内容!')
})
ipcMain.on('xtoms', (ev, data) => {
ev.returnValue = '一条来自主进程的同步回复内容!'
})
- 主进程向渲染进程发送消息
// 主进程
BrowserWindow.getFocusedWindow().webContents.send('mtox', '一条来自主进程的消息!')
// 渲染进程
ipcRenderer.on('mtox', (ev, data) => {
console.log(ev, data);
})
-
渲染进程间通信
- 使用localStorage或者其他数据存储方案进行数据存储和读取
- 渲染进程发送消息到主进程,主进程再发送消息到指定的(可以 通过id获取winodw对象)渲染进程
- 如果要在打开新窗口的 同时发送消息,可以直接使用生产的window对象,但是要在监听到window.webContents.on('did-finish-load')之后发送消息
-
打开web开发者调试工具(方便调试)
mainWindow.webContents.openDevTools()
- 开启文件选择窗口
const { dialog } = require('@electron/remote')
dialog.showOpenDialog({
defaultPath: __dirname,
properties: ['openFile', 'multiSelections'],
filters: [
{ name: 'js代码', extensions: ['js'] }
]
}).then((ret) => {
console.log(ret);
})
- shell:使用默认应用程序来管理文件和URL
shell.openExternal(e.target.getAttribute('href')) // 打开URL
shell.showItemInFolder(path.resolve(__filename)) // 显示文件
shell.openPath(path.resolve(__filename)) // 打开文件
- 全局快捷键的注册和移除
// 注册
globalShortcut.register('ctrl + command + o', () => {
console.log("快捷键注册成功");
})
// 移除 - 如果不移除将一直生效
globalShortcut.register('ctrl + command + o')
globalShortcut.unregisterAll()
- 剪切板的使用
const ret = clipboard.writeText('test')
clipboard.readText(ret)
// 复制图片的时候使用nativeImage
const image = nativeImage.createFromPath('./msg.png')
const imgRet = clipboard.writeImage(image)
const nImg clipboard.readText()
conts imgDom = new Image()
imgDom.src = nImage.toDataURL()
document.body.appendChild(imgDom)
- 项目开发时需要使用到的支持库
- electorn-is-dev - 判断electron是否为开发环境
- concurrently - 连接多个命令,命令用双引号包裹,空格分割
- wait-on - 等待前一个命令的执行完成后,执行后一个命令
- cross-env - 跨平台的配置环境变量,控制编译后的网页内容不在浏览器中展示
// package.json
"scripts":{
"ele": "concurrently \"cross BROWSER=none yarn start\" \"wait-on http://locahost:3000 && elect ron .\""
}
- 在前端(非node环境下)代码中node模块,需要使用window.xx可以进行引入调用
// helper.js
const fs = window.require('fs').promises
// react or vue文件
import { xx, xxx} from './utils/helper'
cost path = window.require('path')
-
Electron store可以实现数据持久化
-
Electron中,除main.js外,其他js操作均处于渲染进程
PS:如果有需要补充的内容,请在评论区留言
转载时请注明“来自掘金 - EvenZhu”