1.系统托盘图标与菜单
import {Menu,Tray,electron} from 'electron'
const path = require('path');
//托盘对象
var appTray = null;
//系统托盘右键菜单
var trayMenuTemplate = [
{
label: '设置',
click: function () {} //打开相应页面
},
{
label: '帮助',
click: function () {}
},
{
label: '关于',
click: function () {}
},
{
label: '退出',
click: function () {
app.quit();
app.quit();//因为程序设定关闭为最小化,所以调用两次关闭,防止最大化时一次不能关闭的情况
}
}
];
//系统托盘图标目录
appTray = new Tray('./static/favicon.ico');//当前index.js文件所在的同级目录
//图标的上下文菜单
const contextMenu = Menu.buildFromTemplate(trayMenuTemplate);
//设置此托盘图标的悬停提示内容
appTray.setToolTip('我的托盘图标');
//设置此图标的上下文菜单
appTray.setContextMenu(contextMenu);
//单击右下角小图标显示应用
appTray.on('click',function(){
mainWindow.show();
});
2.自动更新
①在main/index.js中加入以下代码
import {
autoUpdater
} from 'electron-updater'
// 检测更新,在你想要检查更新的时候执行,renderer事件触发后的操作自行编写
! function updateHandle() {
let message = {
error: '检查更新出错',
checking: '正在检查更新……',
updateAva: '检测到新版本,正在下载……',
updateNotAva: '现在使用的就是最新版本,不用更新',
};
const uploadUrl = "http://192.168.1.108:6126/download/"; // 下载地址,不加后面的**.exe
autoUpdater.setFeedURL(uploadUrl);
autoUpdater.on('error', function(error) {
sendUpdateMessage(message.error)
});
autoUpdater.on('checking-for-update', function() {
sendUpdateMessage(message.checking)
});
autoUpdater.on('update-available', function(info) {
sendUpdateMessage(message.updateAva)
});
autoUpdater.on('update-not-available', function(info) {
sendUpdateMessage(message.updateNotAva)
});
// 更新下载进度事件
autoUpdater.on('download-progress', function(progressObj) {
mainWindow.webContents.send('downloadProgress', progressObj)
})
autoUpdater.on('update-downloaded', function(event, releaseNotes, releaseName, releaseDate, updateUrl, quitAndUpdate) {
ipcMain.on('isUpdateNow', (e, arg) => {
console.log(arguments);
console.log("开始更新");
//some code here to handle event
autoUpdater.quitAndInstall();
});
mainWindow.webContents.send('isUpdateNow')
});
ipcMain.on("checkForUpdate", () => {
//执行自动更新检查
autoUpdater.checkForUpdates();
})
}()
// 通过main进程发送事件给renderer进程,提示更新信息
function sendUpdateMessage(text) {
mainWindow.webContents.send('message', text)
}
②然后在APP.vue中加入以下代码即可
mounted() {
const _this = this
_this.$electron.ipcRenderer.send("checkForUpdate");
_this.$electron.ipcRenderer.on("message", (event,text) => {
console.log(arguments);
_this.tips = text;
console.log(text);
confirm(text)
});
_this.$electron.ipcRenderer.on("downloadProgress", (event, progressObj) => {
_this.downloadPercent = progressObj.percent || 0;
});
_this.$electron.ipcRenderer.on("isUpdateNow", () => {
_this.$electron.ipcRenderer.send("isUpdateNow");
});
},
3.electron打包
打包详见这篇文章,详细介绍了该如何打包,以及打包的坑
https://segmentfault.com/a/1190000018533945?utm_source=tag-newest
----------------------原文分界线-------------------------
vue-electron 执行npm run build时,在build的时候会因为下载远程打包所需文件而超时,然后根据错误一步一步就行手动安装相应的文件。
虽然在网上参考了很多相关方法,最终还是失败,然后屡次尝试后,终于成功了。
附上elelctron相关的淘宝镜像地址:https://npm.taobao.org/mirrors/electron/
step1:npm run build后,第一次报错需要下载 electron-v2.0.18-win32-x64.zip(我这里是需要该版本的文件,根据自己的错误信息,来选择对应的版本下载即可),在镜像中选取该版本号 2.0.18,点击进入,并选择下载 electron-v2.0.18-win32-x64.zip 和 SHASUMS256.txt, 下载完成后,将SHASUMS256.txt文件改成 SHASUMS256.txt-2.0.18,然后将两个文件拷入如图位置:
没有路径的,需要自己该创建路径
step2:完成step1后,继续npm run build,发现又有文件下载失败 winCodeSign-2.4.0(我这里是需要该版本的文件,根据自己的错误信息,来选择对应的版本下载即可),然后自己手动下载 https://github.com/electron-userland/electron-builder-binaries/releases/tag/winCodeSign-2.4.0,这里下载的是Source code(zip),速度快,下载完成后解压,拷贝如图位置所有文件:
拷贝winCodeSign所有文件
拷贝至如图位置:
没有路径的,需要自己该创建路径
step3:完成step2后,继续npm run build,发现又有文件下载失败 nsis-3.0.3.2(同上),然后自己手动下载https://github.com/electron-userland/electron-builder-binaries/releases/tag/nsis-3.0.3.2,同上,下载完成后解压,拷贝如图位置所有文件:
拷贝nsis里所有文件
拷贝至如图位置:
没有路径的,需要自己该创建路径
step4:完成step3后,继续npm run build,发现又有文件下载失败 nsis-resources-3.3.0,但是按照上面的方法操作,最后还是会报错,然后我尝试,用step3中下载解压后的这个nsis-3.0.3.2版本试试,拷贝如图位置所有文件:
拷贝nsis-resources所有文件
拷贝至如图位置:
没有路径的,需要自己该创建路径
至此,我们一共进行了四次拷贝操作,完成以上四步操作后,运行npm run build,不一会儿就能打包成功,得到你的第一个exe版本。
------------------------------------原文结束---------------------------------------------
4.下载文件
①隐藏进度条设置默认下载路径
mainWindow.webContents.session.on('will-download', (e, item) => {
//获取文件的总大小
const totalBytes = item.getTotalBytes();
//设置文件的保存路径,此时默认弹出的 save dialog 将被覆盖 修改第一个参数即可 如: "D:\\test"
const filePath = path.join(app.getPath('downloads'), item.getFilename());
item.setSavePath(filePath);
//监听下载过程,计算并设置进度条进度
item.on('updated', () => {
mainWindow.setProgressBar(item.getReceivedBytes() / totalBytes);
});
//监听下载结束事件
item.on('done', (e, state) => {
//如果窗口还在的话,去掉进度条
if (!mainWindow.isDestroyed()) {
mainWindow.setProgressBar(-1);
}
//下载被取消或中断了
if (state === 'interrupted') {
electron.dialog.showErrorBox('下载失败', `文件 ${item.getFilename()} 因为某些原因被中断下载`);
}
//下载完成,让 dock 上的下载目录Q弹一下下
if (state === 'completed') {
app.dock.downloadFinished(filePath);
}
});
});
5.报错process is not defined问题
找到图中红框部分,添加红框内代码即可解决该问题
源码如下:
plugins: [
new VueLoaderPlugin(),
new MiniCssExtractPlugin({
filename: 'styles.css'
}),
new HtmlWebpackPlugin({
filename: 'index.html',
template: path.resolve(__dirname, '../src/index.ejs'),
templateParameters(compilation, assets, options) {
return {
compilation: compilation,
webpack: compilation.getStats().toJson(),
webpackConfig: compilation.options,
htmlWebpackPlugin: {
files: assets,
options: options
},
process,
};
},
minify: {
collapseWhitespace: true,
removeAttributeQuotes: true,
removeComments: true
},
nodeModules: process.env.NODE_ENV !== 'production' ?
path.resolve(__dirname, '../node_modules') :
false
}),
new webpack.HotModuleReplacementPlugin(),
new webpack.NoEmitOnErrorsPlugin()
],