上一篇介绍了 Electron 的架构,今天来了解一下它到底有什麽 API 供我们使用~
(图片来源:Electronvue开发实战1)
从图可以了解,主进程、渲染进程都各自有可以使用的 API,而有些两边皆可以使用,因为这些功能实在是太多了,接下来就只介绍一些常用的 API
这边介绍的 API 只有主进程能用,无法在渲染进程使用
app 操控整个应用程序的生命周期,常会用来监听与整个应用程序的重要事件
// main.js
const { app } = require('electron')
app.on('window-all-closed', function () {
app.quit()
})
ready
:完成初始化时触发window-all-closed
:所有视窗关闭时触发activate
:唤醒应用程序时触发(macOS)browser-window-created
:视窗被创建时触发browser-window-focus
:视窗被关注时触发browser-window-blur
:视窗被取消关注时触发app.quit()
:关闭所有视窗app.exit()
:退出所有视窗,不会询问用户app.whenReady()
:初始化後执行(回传 Promise
)app.hide()
:隐藏所有视窗(macOS)app.show()
:显示所有视窗(macOS)app.requestSingleInstanceLock()
:视窗是否成功锁定为单一视窗(回传 Boolean
)// main.js
const { app } = require('electron')
let myWindow = null
const gotTheLock = app.requestSingleInstanceLock() // 锁定视窗,并记录回传值
if (!gotTheLock) {
// 开启第二个视窗时无法成功锁定,关闭视窗
app.quit()
} else {
// 开启第二个视窗时触发,将第一个视窗还原并关注
// 此事件为第一个视窗发出
app.on('second-instance', (event, commandLine, workingDirectory) => {
if (myWindow) {
if (myWindow.isMinimized()) myWindow.restore()
myWindow.focus()
}
})
// 正常开启视窗,并储存实例
app.whenReady().then(() => {
// 如果 createWindow 为 Promise,则需使用 than 或 async/await
myWindow = createWindow()
})
}
BrowserWindow 用来建立一个视窗,有许多外观与功能的重要设定,也能监听每个视窗的相关事件
// main.js
const { BrowserWindow } = require('electron')
const path = require('path')
// 以下没特别注记即为预设值
const win = new BrowserWindow({
width: 800, // 宽度
height: 600, // 高度
x: 0, // 左方偏移量,预设置中
y: 0, // 上方偏移量,预设置中
useContentSize: false, // 设定窗口宽高是否包含框架与 Menu
minWidth: 0, // 最小宽度
minHeight: 0, // 最小高度
maxWidth: 1000, // 最大宽度,预设无限制
maxHeight: 1000, // 最大高度,预设无限制
resizable: true, // 可否调整视窗大小
movable: true, // 可否移动视窗
minimizable: true, // 可否最小化
maximizable: true, // 可否最大化
closable: true, // 可否点击关闭按钮
alwaysOnTop: false, // 视窗是否总是在顶部
fullscreen: false, // 视窗是否全萤幕显示
fullscreenable: true, // 可否将视窗全萤幕
Kiosk: false, // 视窗是否开启 Kiosk 模式
title: 'Electron', // 视窗标题
icon: './images/icon.png', // 视窗框架图示
show: true, // 是否显示视窗
frame: false, // 是否隐藏框架 与 Menu
parent: null, // 父视窗
disableAutoHideCursor: false, // 视窗内是否隐藏鼠标
autoHideMenuBar: false, // 是否隐藏 Menu(按下 Alt 可显示)
backgroundColor: '#FFF', // 背景颜色
hasShadow: true, // 视窗是否有阴影
opacity: 0, // 视窗初始不透明度
darkTheme: false, // 视窗是否使用深色模式
transparent: false, // 视窗是否透明(frame 为 true 才有作用)
webPreferences: {
devTools: true, // 是否开启 devtools
nodeIntegration: false, // 渲染进程是否可访问 Node.js
preload: path.join(__dirname, 'preload.js'), // preload.js 文件位置
enableRemoteModule: false, // 是否启用 remote 模块
zoomFactor: 1.0, // 窗口缩放系数
webSecurity: true, // 是否开启同源政策(关闭之後页面才可以打 API)
webgl: true, // 是否启用 WebGL
plugins: false, // 是否启用插件
experimentalFeatures: false, // 是否启用 Chromium 实验功能
backgroundThrottling: true, // 是否在背景运行
}
})
win.loadURL('https://github.com')
// main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow()
win.on('close', (e) => {
// do something...
})
close
:视窗将要关闭时触发blur
:视窗失去焦点时触发focus
:视窗获得焦点时触发show
:视窗显示时触发hide
:视窗隐藏时触发ready-to-show
:视窗可显示时触发maximize
:视窗最大化时触发unmaximize
:视窗退出最大化时触发minimize
:视窗退出最小化时触发restore
:视窗还原最小化时触发will-resize
:调整视窗大小前触发resize
:调整视窗大小时触发resized
:调整视窗大小後触发will-move
:移动视窗前触发move
:移动视窗时触发moved
:移动视窗後触发enter-full-screen
:视窗进入全萤幕时触发leave-full-screen
:视窗退出全萤幕後触发// main.js
const { BrowserWindow } = require('electron')
BrowserWindow.getAllWindows()
BrowserWindow.getAllWindows()
:获取一个包含所有视窗实例的阵列BrowserWindow.getFocusedWindow()
:获取正在关注的视窗实例BrowserWindow.fromId(id)
:获取指定 id 的视窗实例// main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800, height: 1500 })
win.destroy()
win.destroy()
:销毁视窗,仅会发出 closed
事件win.close()
:关闭视窗win.show()
:显示视窗win.hide()
:隐藏视窗win.maximize()
:视窗最大化win.minimize()
:视窗最小化win.restore()
:视窗还原最小化win.setFullScreen(Boolean)
:设定视窗是否全屏win.setSize(width, height)
:设定视窗宽高win.setContentSize(width, height)
:设定视窗宽高(不含框架与 Menu)win.moveTop()
:将视窗移至最上面win.center()
:将视窗移至中间win.setPosition(x, y)
:设定视窗位置win.setTitle(title)
:设定标题win.flashFrame(Boolean)
:设定视窗是否闪烁win.loadURL(url)
:视窗载入该 urlwin.loadFile(filePath)
:视窗载入该档案win.reload()
:重新载入当前网页这边官方提到两个开启视窗的优化小技巧
// main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ show: false })
win.once('ready-to-show', () => {
win.show()
})
// main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ backgroundColor: '#2e2c29' })
win.loadURL('https://github.com')
webContents 跟 BrowserWindow
相当雷同,建立视窗後若需改变该视窗设定则可使用此方法,另外也有一些更细微的操作
// main.js
const { webContents } = require('electron')
webContents.getAllWebContents()
webContents.getAllWebContents()
:获取一个所有视窗的 Array
webContents.getFocusedWebContents()
:获取正在关注的视窗物件webContents.fromId(id)
:获取指定 id 的视窗物件// main.js
const { BrowserWindow } = require('electron')
const win = new BrowserWindow({ width: 800, height: 1500 })
win.webContents.loadURL('http://github.com')
win.webContents.loadURL(url)
:视窗载入该 urlwin.webContents.loadFile(filePath)
:视窗载入该档案win.webContents.reload()
:重新载入当前网页win.webContents.reloadIgnoringCache()
:重新载入当前网页(忽略快取)win.webContents.getURL()
:获取当前网页网址win.webContents.getTitle()
:获取当前网页标题win.webContents.clearHistory()
:清除历史纪录win.webContents.goBack()
:上一页win.webContents.goForward()
:下一页win.webContents.goToIndex(index)
:导航到该索引索面win.webContents.getUserAgent()
:获取此网页用户代理win.webContents.getZoomFactor()
:获取当前缩放系数win.webContents.setZoomFactor(factor)
:设定缩放系数,原始为 1.0win.webContents.openDevTools()
:打开 devtoolswin.webContents.closeDevTools()
:关闭 devtoolswin.webContents.copy()
:复制win.webContents.cut()
:剪下win.webContents.paste()
:贴上win.webContents.undo()
:复原win.webContents.redo()
:重做win.webContents.capturePage([x, y, width, height])
:网页截图(回传 Promise
)win.webContents.send(channel, ...args)
:同 ipcMain.send
win.webContents.startDrag({file, icon})
:操作拖动文件win.webContents.printToPDF(options)
:将网页截图存成 PDF// main.js
const { BrowserWindow } = require('electron')
const fs = require('fs') // 档案操作
const path = require('path') // 路径操作
const os = require('os') // 系统操作
const win = new BrowserWindow({ width: 800, height: 600 })
win.loadURL('http://github.com')
// loading 完成之後执行
win.webContents.on('did-finish-load', () => {
win.webContents.printToPDF({}).then(data => {
// 设定路径为桌面上的 demo.pdf
const pdfPath = path.join(os.homedir(), 'Desktop', 'demo.pdf')
// 将档案创建在该路径
fs.writeFile(pdfPath, data, (error) => {
if (error) throw error
})
}).catch(error => {
// catch error
})
})
Menu 用来建立与设定选单,可直接建立上方工具列的选单,或是其他地方的内容选单
// main.js
const { Menu } = require('electron')
const isMac = process.platform === 'darwin'
// 设定 Menu 样板(Windows 与 MacOS 分开设定)
const template = [
...(isMac ? [{
label: 'A-Menu',
submenu: [
{ role: 'quit' }
]
}] : [{
label: 'B-Menu',
submenu: [
{ role: 'undo' },
{ type: 'separator' },
{ label: '关闭', role: 'quit' }
]
}])
]
// 用样板建立一个选单
const menu = Menu.buildFromTemplate(template)
// 设定应用程序顶部选单
Menu.setApplicationMenu(menu)
Menu.buildFromTemplate(template)
:建构一个选单实例Menu.setApplicationMenu(menu)
:设定顶部选单// main.js
const { ipcMain, BrowserWindow, Menu } = require('electron')
ipcMain.on('click-right', () => {
// 设定 Menu 样板
const template = [
{
label: 'B-Menu',
submenu: [
{ role: 'undo' },
{ type: 'separator' },
{ label: '关闭', role: 'quit' }
]
}
]
// 用样板建立一个选单
const menu = Menu.buildFromTemplate(template)
// 显示弹出选单
menu.popup(BrowserWindow.getFocusedWindow())
})
menu.popup([options])
:显示弹出选单menu.closePopup([browserWindow])
:关闭弹出选单menu.append(menuItem)
:将 menuItem
插入选单最後方menu.insert(pos, menuItem)
:将 menuItem
插入指定位置建立选单 template
可以参考官方文件
如果想要客制化自己的 Menu,可以将 Menu 隐藏,并自己使用刻一个,不过要让自己的视窗可以拖拉记得加上 CSS 属性 -webkit-app-region: drag
,但是不要覆盖到功能按钮,否则按钮会失效
<div class="menu">
<div class="drag">
<img class="icon" src="./icon.png">
<span>title</span>
</div>
<button><img class="icon" src="./minimiz.png"></button>
<button><img class="icon" src="./maximiz.png"></button>
<button><img class="icon" src="./close.png"></button>
</div>
.drag {
-webkit-app-region: drag;
}
Tray 是右下角的图示与功能,使用 Menu
建立选单,须於初始化後调用
// main.js
const { Tray } = require('electron')
const tray = new Tray()
tray.on('click', (e) => {
// do something...
})
click
:图示选单被左键点击时触发right-click
:图示选单被右键点击时触发double-click
:图示选单被双击时触发// main.js
const { app, Menu, Tray } = require('electron')
let tray = null
app.whenReady().then(() => {
// 设定 icon 路径
const tray = new Tray('./images/icon.png')
// 设定选单样板
const contextMenu = Menu.buildFromTemplate([
{ label: 'Item1', click: () => { console.log('click') } },
{ label: 'Item2' },
{ label: 'Item3', type: 'radio', checked: true },
{ label: 'Item4', type: 'radio' }
])
// 右下角 icon 被 hover 时的文字
tray.setToolTip('This is my application.')
// 设定定应用程序右下角选单
tray.setContextMenu(contextMenu)
})
tray.destroy()
:销毁图示选单tray.setToolTip(toolTip)
:设定图示选单被 hover 时的样式tray.displayBalloon(options)
:设显示一个通知(Windows)
icon
:图示路径iconType
:none
、info
、warning
、error
或 custom
,预设为 custom
title
:标题(必填)content
:内容(必填)largeIcon
:是否启用大图示(Boolean),预设为 true
noSound
:是否播放音效(Boolean),预设为 false
respectQuietTime
:勿扰模式不显示通知(Boolean),预设为 false
tray.removeBalloon()
:移除通知(Windows)建立选单 template
可以参考官方文件
Notification 用来建立一个系统通知,使用 new Notification(options)
建立一个通知实例,须於初始化後调用
// main.js
const myNotification = new Notification({
title: '标题',
subtitle: '副标题',
body: '内容',
silent: true,
icon: './images/icon.png',
timeoutType: 'default'
})
title
:标题(必填)body
:内容(必填)subtitle
:副标题(macOS)silent
:是否发出音效(Boolean)icon
:图示路径timeoutType
:通知消失时间,值为 default
或 never
// main.js
app.whenReady().then(() => {
const myNotification = new Notification()
myNotification.on('show', (e) => {
// do something...
})
})
show
:通知显示时触发click
:通知被点击时触发close
:通知关闭时触发// main.js
app.whenReady().then(() => {
const myNotification = new Notification({
title: '标题',
body: '内容'
})
myNotification.show()
})
Notification.show()
:显示通知Notification.close()
:关闭通知通知这边因为各系统都有很多毛,所以如果没有显示请参考官方文件
globalShortcut 用来自定义快捷键,须於初始化後调用
// main.js
const { app, globalShortcut } = require('electron')
app.whenReady().then(() => {
// 注册快捷键 CommandOrControl + 0
const ret = globalShortcut.register('CommandOrControl+0', () => {
// do something...
})
// 返回 Boolean,用於检查快捷键是否注册成功
globalShortcut.isRegistered('CommandOrControl+0')
})
app.on('will-quit', () => {
// 取消注册的快捷键 CommandOrControl + 0
globalShortcut.unregister('CommandOrControl+0')
// 取消所有注册的快捷键
globalShortcut.unregisterAll()
})
globalShortcut.register(accelerator, callback)
:注册快捷键globalShortcut.unregister(accelerator)
:注消快捷键globalShortcut.registerAll(accelerator, callback)
:一次注册多个快捷键,accelerator
为阵列globalShortcut.unregisterAll()
:注消所有快捷键可定义的 accelerator
请参考官方文件
dialog 为弹出视窗,用来开启档案选择视窗或讯息弹出视窗等等
// main.js
const { dialog } = require('electron')
dialog.showOpenDialog({ properties: ['openFile', 'multiSelections'] })
dialog.showOpenDialogSync(options)
:打开档案的弹窗,等待选取档案并返回dialog.showOpenDialog(options)
:打开档案的弹窗(返回一个 Promise
)dialog.showSaveDialogSync(options)
:储存档案的弹窗,等待选取档案并返回dialog.showSaveDialog(options)
:储存档案的弹窗(返回一个 Promise
)title
:标题defaultPath
:预设位置buttonLabel
:确定按钮的文字filters
:可限制档案类型{
filters: [
{ name: 'Images', extensions: ['jpg', 'png', 'gif'] },
{ name: 'Movies', extensions: ['mkv', 'avi', 'mp4'] },
{ name: 'Custom File Type', extensions: ['as'] },
{ name: 'All Files', extensions: ['*'] }
]
}
properties
:其他功能,阵列里面放以下字串
openFile
:可选择文件openDirectory
:可选择资料夹multiSelections
:可选择多个// main.js
const { dialog } = require('electron')
dialog.showMessageBox({ type: 'info', title: '标题', message: '内容' })
dialog.showMessageBoxSync(options)
:讯息的弹窗,等待点选并返回dialog.showMessageBox(options)
:讯息的弹窗(返回一个 Promise
)dialog.showErrorBox(title, content)
:错误视窗type
:类型,none
、info
、error
、question
与 warning
buttons
:按钮文字,一个里面为字串的阵列,选择後回传索引defaultId
:预设选择的按钮索引title
:讯息标题message
:讯息内容detail
:讯息详细文字checkboxLabel
:checkbox 的文字checkboxChecked
:checkbox 预设值icon
:显示的图示cancelId
:取消按钮的索引数,Esc 时返回此索引我们如果设定视窗 alwaysOnTop
时会发现,视窗将 dialog
盖住了,这时候可以用以下方法
// main.js
import { BrowserWindow, dialog } from 'electron'
// 创建另外一个 alwaysOnTop 的视窗,且不显示於画面
const win = new BrowserWindow({ show: false, alwaysOnTop: true })
// 在该视窗显示 dialog,并在回传後将视窗销毁
dialog.showMessageBox(win, { type: 'info', title: '标题', message: '内容' }).then(() => {
win.destroy()
})
这边介绍的 API 在主进程能用,在渲染进程也可以使用,可以将值写入全域,以便在 renderer.js
使用
// preload.js
const { clipboard, shell } = require('electron')
window.clipboard = clipboard
window.shell = shell
clipboard 就是剪贴簿的功能,可记录文字、HTML、图片等等
// main.js
const { clipboard } = require('electron')
clipboard.availableFormats([ 'text/plain', 'text/html' ])
clipboard.writeText('范例字串', 'selection')
console.log(clipboard.readText('selection'))
clipboard.writeText(text)
:将文字写入剪贴簿clipboard.readText()
:读取剪贴簿的文字clipboard.writeHTML(markup)
:将 html 写入剪贴簿clipboard.readHTML()
:读取剪贴簿的 htmlclipboard.writeImage(image)
:将图片写入剪贴簿clipboard.readImage()
:读取剪贴簿的图片clipboard.writeRTF(text)
:将 RTF 写入剪贴簿clipboard.readRTF()
:读取剪贴簿的 RTFclipboard.availableFormats([type])
:定义剪贴簿可用格式clipboard.clear()
:清除剪贴簿内容clipboard.write(data)
:可一次写入多笔资讯
text
:文字html
:htmlimage
:图片rtf
:RTFclipboard.write({
text: 'test',
html: '<b>Hi</b>',
rtf: '{\\rtf1\\utf8 text}',
})
shell 可以使用预设的应用程序开启档案,常用在用浏览器开启档案
// main.js
const { shell } = require('electron')
shell.openExternal('https://github.com')
shell.showItemInFolder(fullPath)
:打开该文件所在目录并选取该文件shell.openPath(path)
:使用预设方式打开该文件shell.openExternal(url)
:使用预设浏览器打开该网址shell.moveItemToTrash(fullPath)
:删除该档案shell.beep()
:播放提示音nativeImage 是一个包装图片的物件,Electron 内许多回传图片都是此类型
// main.js
const { BrowserWindow, Tray, clipboard } = require('electron')
// 以下返回的皆为 nativeImage 物件
const appIcon = new Tray('/Users/somebody/images/icon.png')
const win = new BrowserWindow({ icon: '/Users/somebody/images/window.png' })
const image = clipboard.readImage()
nativeImage.createFromPath(path)
:依路径建立一个 nativeImage
物件nativeImage.createFromBitmap(buffer, options)
:依档案建立一个 nativeImage
物件nativeImage.createFromBuffer(buffer, options)
:依档案建立一个 nativeImage
物件nativeImage.createFromDataURL(dataURL)
:依 dataURL 建立一个 nativeImage
物件nativeImage.createFromPath(path)
:依路径建立一个 nativeImage
物件image.toPNG(path)
:返回 Bufferimage.toJPEG(quality)
:返回 Buffer,quality 为 0 ~ 100image.toBitmap(path)
:返回 Bufferimage.toDataURL(path)
:返回 Stringimage.getBitmap(path)
:返回 Buffer这边介绍的 API 仅在渲染进程能用,无法在主进程使用
remote 是很特别的方法,他的作用是为了让渲染进程使用部分主进程的功能,使用方法如下
// main.js
const { BrowserWindow } = require('electron')
const path = require('path')
const win = new BrowserWindow({
width: 800,
height: 600,
webPreferences: {
preload: path.join(__dirname, 'preload.js'),
enableRemoteModule: true // 启用 remote 模块
}
})
win.loadURL('https://github.com')
// preload.js
const { dialog } = require('electron').remote
window.dialog = dialog
// renderer.js
window.dialog.showErrorBox('标题', '内容')
remote.require(module)
:载入相对路径模块remote.getCurrentWindow()
:回传当前视窗实例emote.getCurrentWebContents()
:回传当前视窗内容实例// preload.js
const foo = require('electron').remote.require('./foo')
require('electron').remote.getCurrentWindow().on('close', () => {
// do something...
})
读文件真的太苦了
>>: [Golang]同步工具-sync包的原子操作(上)-心智图总结
昨天跟大家介绍了网页首图的媒材,那今天针对图片展示的部分来做一个分享,整理出几个常见的网页排版,可以...
主要区别 var: 变数未宣告前使用,会出现undefined var为函式作用域(function...
这是 ISO 27001 的最後一个章节,要表达的精神很简单! 就是如果有人发现【机房的门没有关】,...
目的 假如产品之间有可以负责联系的元素,那依赖该元素找出共同点後建立关联,进而减少工厂的数量,却可以...
优缺点 优点 Block storage最大的优点就是他使得计算与储存分离,我们能轻易地透过LUN ...