搭建项目
vue create vue3-electron
复制代码
cd vue3-electron
vue add electron-builder
复制代码
这里选择v13.0.0的Electron:
Electron13 需要node 的版本 > 14 !多人开发建议锁版本,避免不同版本之间带来的坑!
稍等片刻:
yarn run electron:serve
复制代码
坑
Electron 安装失败
这应该是大部分朋友都会遇上的问题。
最开始的解决方案:
- 删除node_modules/electron
- 再次安装(yarn/cnpm/ --registry registry.npmmirror.com/)
这种方案,有时能成功,有时搞半天都不行。
最终的解决方案:
- 就是到node_modules文件夹里面的electron文件夹里面的install.js
- 然后在这个文件夹下打开terminal,然后输入npm install.js
等待这个运行好之后,基本上就成功了!
打包失败
mac 打包的图标格式为 icns,windows打包的图片格式为ico
这里推荐一个免费好用的图片格式转换工具:convert.72wo.com/icns-to-ico
打包配置:
// vue.config.js
pluginOptions: {
electronBuilder: {
builderOptions: {
win: {
icon: 'src/assets/img/icon.ico'
},
mac: {
icon: 'src/assets/img/icon.icns'
}
}
}
}
复制代码
electron-builder
在打包时会检测cache中是否有electron
包,如果没有的话会从github
上拉取,在国内网络环境中拉取的过程大概率会失败,所以你可以自己去下载一个包放到cache目录里。
各个平台的目录地址
- Linux: $XDG_CACHE_HOME or ~/.cache/electron/
- MacOS: ~/Library/Caches/electron/
- Windows: ~/AppData/Local/electron/Cache/
下载地址: github.com/electron/el…
版本号根据你自己使用的版本来下载!
mac 打包
mac 打包会检查环境中是否有签名钥匙,及其检测是否合法。没有的时候会直接跳过,如果没有签名的文件的话,直接跳过吧。
我们没有现阶段没用弄签名文件,这里暂时没有经验可分享。
windows 打包
windows 打包要手动下载三个文件:
如果打包的时候再下载,基本上都失败。提前下好了,分别放在下面的路径下:
开发的坑
打包后白屏
-
hash路由
-
publicPath: process.env.NODE_ENV === 'production' ? './' : '/',
axios请求失败
axios.defaults.adapter = require('axios/lib/adapters/http')
复制代码
因为electron环境下必须强制使用node的网络请求模块
xcode找不到
设置xcode-select到指定的位置
sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
复制代码
如果安装了多个xcode,则只需要对xcode.app进行替换。
windows 文件路径处理
ES9 之前,\u
表示 unicode 转义,\x
表示十六进制转义,``后跟一个数字表示八进制转义,这使得创建特定的字符串变得不可能,例如Windows文件路径C:\uuu\xxx\111
。
String.raw `C:\Windows\System`
'C:\\Windows\\System'
String.raw `C:\Windows\System`
'C:\Windows\System'
复制代码
ipcRenderer.on多次执行
每次触发ipcRenderer模块都会新建一个新的ipcRenderer,导致ipcRenderer内的函数块会被执行n次(取决于当前残留有多少个ipcRenderer)。
封装server.js: (server在主进程中使用)
import { ipcMain } from 'electron'
const _map = new Map()
ipcMain.on('from-client', (event, params) => {
const reply = function (data) {
event.reply('from-server', {
_symbol: params._symbol,
// data 传递给客户端,最终 resolve 它
data
})
}
const ctx = {
reply,
type: params.type
}
const cb = _map.get(params.type)
if (typeof cb === 'function') {
cb(ctx, params.data)
} else {
cb(ctx, '没有注册~')
}
})
export default function server (type, callback) {
_map.set(type, callback)
}
复制代码
封装request.js:(request在渲染进程中使用)
const { ipcRenderer } = window.require('electron')
const _map = new Map()
ipcRenderer.on('from-server', (event, params) => {
const cb = _map.get(params._symbol)
if (typeof cb === 'function') {
_map.delete(params._symbol)
cb(params.data)
}
})
export default function request (type, data) {
const _symbol = Date.now() + type
return new Promise(resolve => {
_map.set(_symbol, (data) => {
resolve(data)
})
ipcRenderer.send('from-client', {
_symbol: _symbol,
type: type,
data: data
})
})
}
复制代码