全网最详细vue2.5+electron实现桌面应用的排坑日记
简介
今天在开发过程中遇到一个需求,把已经试运行好久的项目打包成桌面应用,遇到了很多坑,做个概述
vue打包
这里需要更改很多配置,要有耐心,但是我最后没用使用这个方法,因为最后页面出来了,但是http请求需要改成完整的url,我项目已经上线很久,工作量太大了,被迫换了一种方式,但也分享一下我浪费了两天阳寿的经历
修复白屏问题
config.js
configpublicPath: '/',修改为publicPath: './',
//如果使用的是Vue-element-admin模板的话,
//记得要把token的存储方式由cookie改为localsotre或者sessionstore
webpack.prod.conf
output中publicPath改为’'./ ",我没记错的话他会覆盖config.js文件中的build配置,所以有这个文件一定要配置
output: {
path: ''’,
filename: '',
chunkFilename: '',
// 修复election打包后页面空白问题
publicPath:'./'
},
路由配置
不支持history,改为默认,当时也就是在这里卡了一个多小时,感兴趣的小伙伴可以学了一下vue路由之间的区别
export default new Router({
// 修复election打包后页面空白问题 注释了就行
// mode: 'history',
修复页面图片报错
build文件夹tuils.js中增加以下代码
if (options.extract) {
return ExtractTextPlugin.extract({
use: loaders,
fallback: 'vue-style-loader',
// 修复election打包后页面空白问题(修复图片空白问题)
publicPath:'../../'
})
} else {
return ['vue-style-loader'].concat(loaders)
}
以上的配置都改好以后就不用在动vue的配置了
electron使用
1.初始化node项目,生成package.json文件
npm init
2.安装electron,并保存为开发依赖项
npm install electron -D
3.根目录下新建main.js文件
const {app, BrowserWindow} = require('electron')
let mainWindow
function createWindow () {
mainWindow = new BrowserWindow({width: 800, height: 600})
mainWindow.loadFile('index.html')
// mainWindow.webContents.openDevTools()
mainWindow.on('closed', function () {
mainWindow = null
})
}
app.on('ready', createWindow)
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') {
app.quit()
}
})
app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open.
if (mainWindow === null) {
createWindow()
}
})
// Root: HKLM; Subkey: "SOFTWARE\Microsoft\Windows\CurrentVersion\Run"; ValueType: string; ValueName: "testrun"; ValueData: "{app}\{#MyAppExeName}"
4、根目录下新建index.html文件
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<h1>Hello Electron!!</h1>
</body>
</html>
5、打开package.json文件,新建命令
"scripts": {
"start": "electron ."
}
6、运行electron看一下效果
npm start
效果图
目前为止,一个最糙的demo就完成了,有科技的小伙伴也可以直接去GitHub上去拉取压缩包,解压后和我的差不多也一样,只是目录结构有点区别但是也大差不差都是一样的逻辑,不用纠结,因为页面展示的内容最后会项目取代,这一步就是为了测试一下能不能运行起来
安装electron-packager生成exe文件
删除election中的index.html,直接把打包好的dist文件放进当前文件夹
运行以下命令:
npm install --save-dev electron-packager
cnpm install --save-dev electron-packager
yarn install --save-dev electron-packager
建议使用cnpm, election下载链接在github,国内很慢
package.json配置打包命令
"scripts": {
"start": "electron .",
"pack": "electron-packager . myClient --win --out ../myClient --arch=x64 --app-version=0.0.1 --electron-version=2.0.0"
}
命令结构如下(根据实际情况修改):
“.”:需要打包的应用目录(即当前目录),
“myClient”:应用名称,
“–win”:打包平台(以Windows为例),
“–out …/myClient”:输出目录,
“–arch=64”:64位,
“–app-version=0.0.1”:应用版本,
“–electron-version=2.0.0”:electron版本
运行打包命令
npm run packager
到此一个桌面应用就声生成完毕了
排坑日记
页面加载正常,接口请求失败
不出意外你们的http请求会被替换成file或者app,反正就是路径的问题,需要把接口改为完整Url,由于我的项目是二开,工作量太大,所以换了一种方式
//mainWindow.loadFile('index.html')
// 用的线上的url 就没问题
mainWindow.loadURL('https://www.baidu.com/')
这种方式好处就是你的项目有改动直接更新线上代码就行,不需要频繁的打包升级,虽然有点违背桌面应用的原理,但是我觉得electron本来就是基于node的所以直接使用url反而是一种捷径,可以省略很多因代码改动引发的繁琐且重复的流程(反正就很爽,打包一次就可以了)
element基础配置
实现最小化到系统托盘
// 窗口最小化
mainWindow.on('minimize', ev => {
// 阻止最小化
ev.preventDefault();
// 隐藏窗口
mainWindow.hide();
});
// 托盘图标被双击
tray.on('double-click', () => {
// 显示窗口
mainWindow.show();
});
// 窗口隐藏
mainWindow.on('hide', () => {
// 启用菜单的显示主窗口项
menu.getMenuItemById('show-window').enabled = true;
// 重新设置系统托盘菜单
tray.setContextMenu(menu);
});
// 窗口显示
mainWindow.on('show', () => {
// 禁用显示主窗口项
menu.getMenuItemById('show-window').enabled = false;
// 重新设置系统托盘菜单
tray.setContextMenu(menu);
});
// 退出程序,销毁窗口
mainWindow.on('destroy', () => {
app.exit()
})
创建系统托盘
tray = new Tray(path.join(__dirname, './img/logo.ico'));
// 菜单模板
let menu = [
{
label: '显示主窗口',
id: 'show-window',
enabled: !mainWindow.show,
click() {
mainWindow.show();
}
},
{
label: '退出',
role: 'quit'
}
];
// 构建菜单
menu = Menu.buildFromTemplate(menu);
// 给系统托盘设置菜单
tray.setContextMenu(menu);
electron中隐藏顶部菜单
mainWindow.setMenu(null)
默认全屏
mainWindow = new BrowserWindow({ fullscreen: true })
给托盘图标设置气球提示
tray.setToolTip('气球提示');
完整代码
const { Tray, Menu, app, BrowserWindow } = require('electron');
const path = require('path');
let tray = null; // 用来存放系统托盘
app.on('ready', () => {
mainWindow = new BrowserWindow({
width: 800,
height: 500,
// 下面这行代码就是配置窗口图标的核心代码了
icon: path.join(__dirname, './img/logo.ico'),
// fullscreen: true,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
}
});
// 创建系统托盘
tray = new Tray(path.join(__dirname, './img/logo.ico'));
// 菜单模板
let menu = [
{
label: '显示主窗口',
id: 'show-window',
enabled: !mainWindow.show,
click() {
mainWindow.show();
}
},
{
label: '退出',
role: 'quit'
}
];
// electron中隐藏顶部菜单
mainWindow.setMenu(null)
// 默认全屏
// mainWindow = new BrowserWindow({ fullscreen: true })
// 构建菜单
menu = Menu.buildFromTemplate(menu);
// 给系统托盘设置菜单
tray.setContextMenu(menu);
// 给托盘图标设置气球提示
tray.setToolTip('零零易消防');
// 用的线上的url 就没问题
mainWindow.loadURL('https://www.baidu.com/')
// 开发者工具
// mainWindow.webContents.openDevTools()
// 窗口最小化
mainWindow.on('minimize', ev => {
// 阻止最小化
ev.preventDefault();
// 隐藏窗口
mainWindow.hide();
});
// 托盘图标被双击
tray.on('double-click', () => {
// 显示窗口
mainWindow.show();
});
// 窗口隐藏
mainWindow.on('hide', () => {
// 启用菜单的显示主窗口项
menu.getMenuItemById('show-window').enabled = true;
// 重新设置系统托盘菜单
tray.setContextMenu(menu);
});
// 窗口显示
mainWindow.on('show', () => {
// 禁用显示主窗口项
menu.getMenuItemById('show-window').enabled = false;
// 重新设置系统托盘菜单
tray.setContextMenu(menu);
});
// 退出程序,销毁窗口
mainWindow.on('destroy', () => {
app.exit()
})
});
恭喜你!能走到这步说明你已经成功了,今天就分享到这里了,有什么问题可以私信我,但是目前并不方遍使用,明天分享如何制作成一个安装包并生成桌面快捷方式的教程
效果图: