一、Electron介绍
Electron 是一个由 GitHub 及泛滥贡献者组成的沉闷社区独特保护的开源我的项目. 应用 JavaScript,HTML 和 CSS 构建跨平台的桌面应用程序
1. 特点
- 跨平台 能够打包成Mac、Windows 和 Linux三个平台的应用程序
- 简化桌面端开发 (1)Electron 基于 Chromium 和 Node.js,能够应用 HTML, CSS 和 JavaScript 构建利用 (2)提供Electron api 和 NodeJS api
- 社区沉闷
2. 兼容性
xp无缘了, 可能须要应用nwjs等计划
二、我的项目搭建
1. 应用 vue cli 创立vue我的项目
vue create electron-test复制代码
2. 装置插件 vue-cli-plugin-electron-builder
vue add electron-builder复制代码
3. 装置完插件后, 我的项目中的一些变动
① package.json 新增了几个scripts
npm run electron:serve electron开发模式npm run electron:build electron打包复制代码
postinstall 和 postuninstall 是为了确保装置或者移除依赖时, 始终跟electron匹配
② 新增了background.js文件
主过程相干操作, 写在这个文件中
③ 新增了一个环境变量
能够用来判断是否在electron状态
process.env.IS_ELECTRON复制代码
三、开发总结
1. 配置我的项目图标
应用electron-icon-builder
, 生成合乎Electron的图标
① 装置
npm install --save-dev electron-icon-builder复制代码
② package.json
中配置生成命令
"electron:generate-icons": "electron-icon-builder --input=./public/icon.png --output=build --flatten"复制代码
③ 生成图标
npm run electron:generate-icons复制代码
④ 应用
import path from 'path'const win = new BrowserWindow({ icon: path.join(__static, 'icon.png')})复制代码
2. 我的项目开发模式运行呈现 Failed to fetch extension 正告
因为网络问题, 开发模式无奈下载 vue devtool 导致的正告, 须要在 background.js 中正文掉下载代码
3. 我的项目应用本地的vue devtools
① 首先能够将vue devtools的代码clone下来, 而后进行编译
git clone https://github.com/vuejs/vue-devtools.gitcd vue-devtoolsnpm installnpm run build复制代码
而后把vue-devtools/packages/shell-chrome
文件夹复制到我的项目根目录
② 在background.js
文件的app.on('ready',
生命周期中进行加载
// 应用本地的vue开发者工具session.defaultSession.loadExtension(path.resolve('shell-chrome'))复制代码
③ 创立窗口的时候应用上面示例办法, 即可失常显示出vue开发者工具
// src/background.jsif (process.env.WEBPACK_DEV_SERVER_URL) { await transferWin.loadURL( process.env.WEBPACK_DEV_SERVER_URL + '/#/test' ) if (!process.env.IS_TEST) transferWin.webContents.openDevTools()} else { transferWin.loadURL('app://./index.html' + '/#/test')}复制代码
4. 渲染过程中如何应用NodeJS api
须要在 vue.config.js 中配置 nodeIntegration 为 true
module.exports = { pluginOptions: { electronBuilder: { nodeIntegration: true } }}复制代码
或者在创立窗口时配置
win = new BrowserWindow({ width: 500, height: 400, frame: false, transparent: true, backgroundColor: '#00000000', // 当敞开开发者工具时, 会从新创立一个新的渲染视图, 所以会应用配置的背景色彩, 如果没配置会应用默认值红色 webPreferences: { nodeIntegration: true, // 渲染层能够应用node webSecurity: false, // 跨域 enableRemoteModule: true // 能够应用remote }, // eslint-disable-next-line no-undef icon: path.resolve(__static, 'logo.png') })复制代码
5. 让创立的窗口能够跨域
创立窗口的时候配置 webSecurity: false
即可
6. 如何监听窗口的状态, 最小化, 聚焦, 窗口暗藏, 窗口显示, 窗口敞开
// 窗口最小化触发win.on('minimize', () => { console.log('最小化')})win.on('focus', () => { console.log('聚焦')})// 窗口暗藏, 任务栏没有图标win.on('hide', () => { console.log('暗藏')})win.on('show', () => { flashTray(false) console.log('显示')})复制代码
7. 如何创立托盘图标
let tray = nullfunction createTray () { tray = new Tray(path.resolve(__static, ‘logo.png’)) // 设置托盘图标 const contextMenu = Menu.buildFromTemplate([ new MenuItem({ label: '退出程序', click: () => { isQuit = true app.exit() } }) ]) tray.setContextMenu(contextMenu) // 设置右键菜单 tray.on(‘click’, () => { // 托盘点击事件 if (win.isVisible()) { win.focus() } else { win.show() } })}复制代码
监听主窗口的敞开, 如果不是齐全退出,
则只是暗藏窗口
win.on('close', e => { if (isQuit) { win = null } else { e.preventDefault() win.hide() }})复制代码
8. 托盘闪动与任务栏闪动
① 托盘闪动原理就时定时的切换托盘的图标, 图标与透明图标的切换
let flashIntervalfunction flashTray (bool) { if (!bool) { flashInterval && clearInterval(flashInterval) tray.setImage(path.resolve(__static, 'logo.png')) return } flashInterval && clearInterval(flashInterval) var count = 0 flashInterval = setInterval(function() { if (count++ % 2 == 0) { tray.setImage(path.resolve(__static, 'empty.png')) } else { tray.setImage(path.resolve(__static, 'logo.png')) } }, 400)}复制代码
② 任务栏的闪动
win.flashFrame(true) // 高亮复制代码
9. 如何只运行单个实例
如果你的程序是利用的次要实例并且当app.requestSingleInstanceLock()返回true时,你应该持续让你的程序运行。如果当它返回 false,
那就立刻退出
const gotTheLock = app.requestSingleInstanceLock()if (!gotTheLock) { app.quit()} { app.on('second-instance', (event, argv) => { if (process.platform === 'win32') { if (win) { if (win.isMinimized()) { win.restore() } if (win.isVisible()) { win.focus() } else { win.show() } } } })}复制代码
10. 主过程与渲染过程如何通信
参考文档:
ipcMain ipcRenderer
① 渲染过程
const {ipcRenderer} = require('electron')ipcRenderer.send('message', 'ping') // 发送给主过程ipcRenderer.on('message-reply', (event, arg) => { console.log(arg) // pong}复制代码
②
主过程
// 监听渲染过程信息ipcMain.on('message', (event, arg) => { console.log('ping') event.sender.send('message-reply', 'pong') // 回复子程序})// 主过程独自往渲染过程发信息win.webContents.send('message-reply', 'pong')复制代码
11. 打包问题
应用nsis打包windows程序的安装包 在 vue.config.js 中配置打包
配置
module.exports = { pluginOptions: { electronBuilder: { builderOptions: { win: { target: [{ target: 'nsis', arch: ['ia32', 'x64'] }] }, nsis: { oneClick: false, // 一键装置 perMachine: true, // 为所有用户装置 allowElevation: true, // 容许权限晋升, 设置 false 的话须要从新容许安装程序 allowToChangeInstallationDirectory: true, // 容许更改装置目录 createDesktopShortcut: true, // 创立桌面图标 createStartMenuShortcut: true, // 创立开始菜单 deleteAppDataOnUninstall: true, include: './public/nsis/installer.nsh', // 蕴含的脚本 guid: '53fe4cba-120d-4851-3cdc-dccb3a469019' // 软件guid } } } }}复制代码
12. 从网页关上程序
① 主过程注册
app.removeAsDefaultProtocolClient(‘testapp’)app.setAsDefaultProtocolClient(‘testapp’)复制代码
② 在nsis打包配置文件(installer.nsh)中增加配置 在装置的时候在注册表注册URL protocol
!macro customInstall DetailPrint 'Register testapp URI Handler' DeleteRegKey HKCR 'testapp' WriteRegStr HKCR 'testapp' '' 'URL:testapp' WriteRegStr HKCR 'testapp' 'URL Protocol' '' WriteRegStr HKCR 'testappshell' '' '' WriteRegStr HKCR 'testappshellOpen' '' '' WriteRegStr HKCR 'testappshellOpencommand' '' '$INSTDIR${APP_EXECUTABLE_FILENAME} %1'!macroend复制代码
③ 间接在浏览器拜访链接即可触发关上客户端 testapp://?参数=值
④ 获取网页端传来的参数
// window 零碎中执行网页调起利用时,解决协定传入的参数const handleArgvFromWeb = (argv) => { console.log(argv) const url = argv.find(v => v.indexOf(`${URLSCHEME}://`) !== -1) console.log(url) if (url) handleUrlFromWeb(url)}// 进行解决网页传来 url 参数,参数自定义,以下为示例// 示例调起利用的 url 为 testapp://?token=205bdf49hc97ch4146h8124h8281a81fdcdbconst handleUrlFromWeb = (urlStr) => { console.log(urlStr) const urlObj = new URL(urlStr) const { searchParams } = urlObj const token = searchParams.get('token') console.log(token)}复制代码
能够看到获取的参数是个数组, 咱们就时要获取最初一项
生产模式下, 如果软件没有提前关上, 通过网页开启时, 须要依照下图形式来获取参数
若提前开启, 则在判断单例的条件判断中获取
13. 装置依赖或打包时呈现electron包下载过慢问题
根目录创立 .npmrc 文件
registry = https://registry.npm.taobao.org sass_binary_site = https://npm.taobao.org/mirrors/node-sass/phantomjs_cdnurl = http://cnpmjs.org/downloadselectron_mirror = https://npm.taobao.org/mirrors/electron/sqlite3_binary_host_mirror = https://foxgis.oss-cn-shanghai.aliyuncs.com/profiler_binary_host_mirror = https://npm.taobao.org/mirrors/node-inspector/chromedriver_cdnurl = https://cdn.npm.taobao.org/dist/chromedriver复制代码
14. 通过里面浏览器关上链接
const { shell } = require('electron')shell.openExternal('https://www.bing.com')复制代码
15. 开发模式如果关上窗口时, 若开启了开发者工具, 想敞开窗口, 须要先把开发者工具敞开, 能力失常敞开窗口
在窗口敞开前, 判断开发者工具是否开启, 若开启则先敞开开发者工具, 例如
if (callWin.isDevToolsOpened()) { callWin.closeDevTools()}复制代码
16. 通明无边框窗口, 接触到屏幕边缘会呈现彩色边框问题
次要就是创立窗口时增加延
时,
setTimeout(() => createWindow(), 400)复制代码
而后敞开硬件加速
app.disableHardwareAcceleration()app.commandLine.appendSwitch('disable-gpu')app.commandLine.appendSwitch('disable-software-rasterizer')复制代码
17. 通明无边框窗口, 当敞开开发者工具时, 背景会变红色问题
当敞开开发者工具时, 会从新创立一个新的渲染视图, 所以会应用配置的背景色彩, 如果没配置会应用默认值红色 所以须要在窗口创立时设置backgroundColor
属性为#00000000
18. 渲染过程获取主过程环境变量
const { remote } = require('electron')const envData = remote.getGlobal('process').env复制代码
19. 打包时, 报错asar文件被占用
vscode能够再setting.json里配置疏忽dist_electron文件夹
"files.exclude": { "dist_electron": true,}复制代码
20. 软件更新
应用electron-updater
① 配置vue.config.js
设置publish
配置, 配置了这个配置后, 打包后会生成一个latest.yml
文件, 须要将其和安装包放在服务器同一目录下, url
配置成服务器能够拜访到这个目录的url, 也能够应用autoUpdater.setFeedURL(url)
动静配置url
pluginOptions: { electronBuilder: { builderOptions: { publish: [ { provider: 'generic', url: 'http://127.0.0.1:5000' } ] } }}复制代码
21. electron win7问题
① win7 sp1 or win8 needed install KB4019990 patch to resolve this issue for now(note:none sp1 win7 needed to upgrade to sp1 before install the patch) 须要装置补丁解决黑屏问题
② 降级.net
③ 敞开硬件加速
22. 7z解压asar插件
目前我用asar命令行解压会报错, 然而用7z的插件尽管报错, 却能够残缺解压 插件地址: https://www.tc4shell.com/en/7...
下载好, 把dll复制到7z装置目录下新建一个Formats
文件夹中