vue2+electron开发桌面端应用并实现自动更新

需求:开发桌面端一体机应用:先把架构搭好就会事半功倍。

我的个人博客

新建项目

vue create demo

安装electron

yarn add electron   //可以省略 安装electron-builder时会自动安装

添加打包工具

vue add electron-builder

在这里插入图片描述
在这里插入图片描述

安装后src下会生成background.js文件

package.json也会生成对应的命令

并把background.js作为入口文件

	"electron:build": "vue-cli-service electron:build",
	"electron:serve": "vue-cli-service electron:serve",

在这里插入图片描述

打包时遇到的error ERR_ELECTRON_BUILDER_CANNOT_EXECUTE

解决方法

1、下载 与当前elecron本版一致的 win32-x64 然后放到 参考路径 : C:\Users\Admin/AppData\Local\electron\Cache
2 、下载 对应的 winCodeSign 解压后 放到 C:\User\Admin/AppData\Local\electron-builder\Cache 没有 winCodeSign 文件夹 自己新建
3、 下载对应的 nsis 和 对应的 nsis-resources 放到 C:\User\Admin/AppData\Local\electron-builder\Cache/nsis 下面

注:复制错误提示里面的链接下载
比如下面的错 :复制https://github.com/electron/electron/releases/download/v20.0.0/electron-v20.0.0-win32-x64.zip进行下载 然后执行上面1的步骤即可解决。

PS:这里要注意的是可能有版本相关的问题(我有两个项目,两个项目下载的版本不一样。一个13.6.9一个20)

在这里插入图片描述

background.js

'use strict'

import {
	app,
	protocol,
	BrowserWindow,
	Menu
} from 'electron'
import {
	createProtocol
} from 'vue-cli-plugin-electron-builder/lib'


import installExtension, {
	VUEJS_DEVTOOLS
} from 'electron-devtools-installer'

const isDevelopment = process.env.NODE_ENV !== 'production'

// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{
	scheme: 'app',
	privileges: {
		secure: true,
		standard: true,
		supportFetchAPI: true  //解决引入外部js时打包后报错Fetch API cannot load app://.ZwCloud2DSDK/ZwWasmJs.wasm.
URL
scheme
is not supported.
	}
}])

async function createWindow() {
	// Create the browser window.
	Menu.setApplicationMenu(null) //隐藏菜单栏
	const win = new BrowserWindow({
		// width: 1900, //最大宽高 不设置则自适应
		// height: 1600,
		//fullscreen: true,//默认全屏
		show: false,
		webPreferences: {
			nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
			contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION
		}
	})
	win.maximize();//窗口最大化
	win.show();
	// win.webContents.openDevTools()
	if (process.env.WEBPACK_DEV_SERVER_URL) {
		// Load the url of the dev server if in development mode
		await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
		if (!process.env.IS_TEST) win.webContents.openDevTools()  //调试工具
	} else {
		createProtocol('app')
		// Load the index.html when not in development
		win.loadURL('app://./index.html')
	}
}

// Quit when all windows are closed.
app.on('window-all-closed', () => {
	// On macOS it is common for applications and their menu bar
	// to stay active until the user quits explicitly with Cmd + Q
	if (process.platform !== 'darwin') {
		app.quit()
	}
})

//点击关闭
app.on('quit', () => {
	app.quit()
})

app.on('activate', () => {
	// On macOS 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 (BrowserWindow.getAllWindows().length === 0) createWindow()
})

// This method will be called when Electron has finished
// initialization and is ready to create browser windows.
// Some APIs can only be used after this event occurs.
app.on('ready', async () => {
	if (isDevelopment && !process.env.IS_TEST) {
		// Install Vue Devtools
		try {
			await installExtension(VUEJS_DEVTOOLS)
		} catch (e) {
			console.error('Vue Devtools failed to install:', e.toString())
		}
	}
	createWindow()
})

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
	if (process.platform === 'win32') {
		process.on('message', (data) => {
			if (data === 'graceful-exit') {
				app.quit()
			}
		})
	} else {
		process.on('SIGTERM', () => {
			app.quit()
		})
	}
}

运行 electron:serve 命令就可以启动成功了。

打包运行 electron:build命令

更多配置参考 electron官方文档

自动更新 electron-updater

1、安装依赖 yarn add electron-updater

2、自定义更新的文件 handleUpdate.js

注: 打包完会生成一个latest.yml文件,把这个文件和生成的.exe文件放在服务器上,会自动检测版本

在这里插入图片描述

import {
	autoUpdater
} from 'electron-updater'

import {
	ipcMain,dialog
} from 'electron'
let mainWindow = null;
export function handleUpdate(window, feedUrl) {
	mainWindow = window;
	let message = {
		error: '检查更新出错',
		checking: '正在检查更新……',
		updateAva: '检测到新版本,正在下载……',
		updateNotAva: '现在使用的就是最新版本,不用更新',
	};

`autoUpdater.autoDownload = false;` //取消自动下载
	//设置更新包的地址
	autoUpdater.setFeedURL(feedUrl);
	//监听升级失败事件
	autoUpdater.on('error', function(error) {
		sendUpdateMessage({
			cmd: 'error',
			message: error
		})
	});
	//监听开始检测更新事件
	autoUpdater.on('checking-for-update', function(message) {
		sendUpdateMessage({
			cmd: 'checking-for-update',
			message: message
		})
	});
	//监听发现可用更新事件
	autoUpdater.on('update-available', function(message) {
		sendUpdateMessage({
			cmd: 'update-available',
			message: message
		})
		//新加内容
	/**	`const options = {
			type: 'info',
			buttons: ['确定', '取消'],
			title: '更新提示',
			message: '发现有新版本,是否更新?',
			cancelId: 1
		}
		dialog.showMessageBox(options).then(res => {
			if (res.response === 0) {
				sendUpdateMessage({
					cmd: 'confimUpdate',
					message: message
				})
				autoUpdater.downloadUpdate()
			} else {
				return;
			}
		})`*/




	});
	//监听没有可用更新事件
	autoUpdater.on('update-not-available', function(message) {
		sendUpdateMessage({
			cmd: 'update-not-available',
			message: message
		})
	});

	// 更新下载进度事件
	autoUpdater.on('download-progress', function(progressObj) {
		sendUpdateMessage({
			cmd: 'download-progress',
			message: progressObj
		})
	});
	//监听下载完成事件
	autoUpdater.on('update-downloaded', function(event, releaseNotes, releaseName, releaseDate, updateUrl) {
		sendUpdateMessage({
			cmd: 'update-downloaded',
			message: {
				releaseNotes,
				releaseName,
				releaseDate,
				updateUrl
			}
		})
		//退出并安装更新包
		//autoUpdater.quitAndInstall();
	});
	//新增
	ipcMain.on("quit-install", (e, arg) => {
		autoUpdater.quitAndInstall();
	})
	//接收渲染进程消息,开始检查更新
	ipcMain.on("checkForUpdate", (e, arg) => {
		//执行自动更新检查
		// sendUpdateMessage({cmd:'checkForUpdate',message:arg})
		autoUpdater.checkForUpdates();
	})
}
//给渲染进程发送消息
function sendUpdateMessage(text) {
	mainWindow.webContents.send('message', text)
}

3、在主进程文件background.js里面引用 handleUpdate.js

`const {
	handleUpdate
} = require('./handleUpdate.js') //根据自己路径引入 我是跟background.js同级放的`

if (process.env.WEBPACK_DEV_SERVER_URL) {
	await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
	if (!process.env.IS_TEST) win.webContents.openDevTools()  //调试工具
} else {
	createProtocol('app')
	win.loadURL('app://./index.html')
}

`//检查更新
handleUpdate(win, ".exe文件存放路径")`     

在app.vue里面渲染更新进度样式

<template>
	<div id="app">
		<MainPage></MainPage>
		//2023/3/21  根据user要求改为静默式更新  只提示用户安装即可
	<!--	<el-dialog title="正在更新新版本,请稍候..." :visible.sync="dialogVisible" width="50%"
			:close-on-click-modal="closeOnClickModal" :close-on-press-escape="closeOnPressEscape"
			:show-close="showClose" center>
			<div style="width:100%;height:50vh;line-height:50vh;text-align:center">
				<el-progress :stroke-width="26" :percentage="percentage" :width="strokeWidth" :show-text="true"
					type="circle"></el-progress>
			</div>
		</el-dialog>-->
	</div>
</template>
<script>
	let ipcRenderer = require("electron").ipcRenderer;
	import MainPage from './views/MainPage.vue'
	export default {
		components: {
			MainPage
		},
		data() {
			return {
				dialogVisible: false,
				closeOnClickModal: false,
				closeOnPressEscape: false,
				showClose: false,
				percentage: 0,
				strokeWidth: 400,
				timer:0
			}
		},
		created() {
			
		},
		unmounted() {
			clearInterval(this.timer)
		},
		mounted() {
			let _this = this;
			//新增 
			this.timer = setInterval(() => {
				setTimeout(() => {
					ipcRenderer.send("checkForUpdate");
				}, 1)
			}, 60000 * 60 * 2)

			//接收主进程版本更新消息
			ipcRenderer.on("message", (event, arg) => {
				//新增内容
				/**`if ("confimUpdate" == arg.cmd) {
						_this.dialogVisible = true;
					} else if ("download-progress" == arg.cmd) {
						console.log(arg.message.percent);
						let percent = Math.round(parseFloat(arg.message.percent));
						_this.percentage = percent;
					} else if ("error" == arg.cmd) {
						_this.dialogVisible = false;
						_this.$message("更新失败");
					}`*/
					//2023/03/21改为如下
				
				if ("update-downloaded" == arg.cmd) {
					_this.$alert('新版本已经下载完成', '提示信息', {
						confirmButtonText: '立即安装',
						callback: (action) => {
							ipcRenderer.send("quit-install")
						}
					});
				}
			   
			
			});
		
		}

	}
</script>

效果图(没有了,不是这个效果了)
在这里插入图片描述

在这里插入图片描述

新的效果:

在这里插入图片描述

自定义安装路径

打包安装默认是直接装在c盘的

新建vue.config.js

module.exports = {
	pluginOptions: {
		electronBuilder: {
			nodeIntegration: true,
			builderOptions: {
				nsis: {
					allowToChangeInstallationDirectory: true, //自定义安装路径
					oneClick: false,
				},
				win: {
					publish: [{
						provider: "generic",
						url: "存放exe文件路径"  //更新包地址  
					}],
				},
				productName: 'xxx'  //项目名
			}
		},
	}
}

ps: 百度时 网上好多资料都是说直接在package.json的build里面

直接加上

nsis: {
allowToChangeInstallationDirectory: true, //自定义安装路径
oneClick: false,
},

这并不适用于我的项目,所以新建了vue.config.js。

在这里插入图片描述

我这里是更新 所以直接跳过了自定义安装路径的那一步,第一次安装可以自己选择路径。

修改 项目打包安装图标

1、安装依赖 生成图标

yarn add electron-icon-builder

2、在package.json的script中添加命令

"electron:generate-icons": "electron-icon-builder --input=./public/icon.png --output=build --flatten"

3、运行 yarn electron:generate-icons 后会生成一个build文件夹(先要放一张icon.png)

在这里插入图片描述

4、删除dist_electron文件夹 重新运行打包命令即可

yarn electron:build

5、图标已更改

在这里插入图片描述

笔记是后面写了 没有对比图 本来默认的是electron的图标

最后放一下完整的background.js文件

'use strict'

import {
	app,
	protocol,
	BrowserWindow,
	Menu
} from 'electron'
import {
	createProtocol
} from 'vue-cli-plugin-electron-builder/lib'


import installExtension, {
	VUEJS_DEVTOOLS
} from 'electron-devtools-installer'

const {
	handleUpdate
} = require('./handleUpdate.js') //根据自己路径引入
const isDevelopment = process.env.NODE_ENV !== 'production'
const path = require('path')
// Scheme must be registered before the app is ready
protocol.registerSchemesAsPrivileged([{
	scheme: 'app',
	privileges: {
		secure: true,
		standard: true
	}
}])

async function createWindow() {
	// Create the browser window.
	Menu.setApplicationMenu(null) //隐藏菜单栏
	const win = new BrowserWindow({
		// width: 1900, //最大宽高 不设置则自适应
		// height: 1600,
		//fullscreen: true,//默认全屏
		show: false,
		icon: path.join(__static, "../public/favicon.ico"), //标题图标
		webPreferences: {
			nodeIntegration: process.env.ELECTRON_NODE_INTEGRATION,
			contextIsolation: !process.env.ELECTRON_NODE_INTEGRATION
		}
	})
	win.maximize();//默认打开窗口最大化
	win.show();
	// win.webContents.openDevTools()
	if (process.env.WEBPACK_DEV_SERVER_URL) {
		// Load the url of the dev server if in development mode
		await win.loadURL(process.env.WEBPACK_DEV_SERVER_URL)
		if (!process.env.IS_TEST) win.webContents.openDevTools()  //调试工具
	} else {
		createProtocol('app')
		// Load the index.html when not in development
		win.loadURL('app://./index.html')
	}

	//检查更新
	handleUpdate(win, ".exe文件存放路径  和vue.config.js文件里的一致")

}

// Quit when all windows are closed.
app.on('window-all-closed', () => {
	// On macOS it is common for applications and their menu bar
	// to stay active until the user quits explicitly with Cmd + Q
	if (process.platform !== 'darwin') {
		app.quit()
	}
})

app.on('quit', () => {
	app.quit()
})

app.on('activate', () => {
	
	if (BrowserWindow.getAllWindows().length === 0) createWindow()
})

app.on('ready', async () => {
	if (isDevelopment && !process.env.IS_TEST) {
		// Install Vue Devtools
		try {
			await installExtension(VUEJS_DEVTOOLS)
		} catch (e) {
			console.error('Vue Devtools failed to install:', e.toString())
		}
	}
	createWindow()
})

// Exit cleanly on request from parent process in development mode.
if (isDevelopment) {
	if (process.platform === 'win32') {
		process.on('message', (data) => {
			if (data === 'graceful-exit') {
				app.quit()
			}
		})
	} else {
		process.on('SIGTERM', () => {
			app.quit()
		})
	}
}

项目总体目录结构

在这里插入图片描述
安装依赖卡的解决办法:npm config set electron_mirror https://npm.taobao.org/mirrors/electron/
后来搞了个入门案例 但是没有做更新 实现方式 electron+vite+vue3+pinia 跟上面有出入 不太影响 适合新人学习使用
项目下载

  • 5
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 13
    评论
### 回答1: VueElectron是一个基于Vue.jsElectron的框架,它可以帮助开发人员快速构建跨平台的桌面应用程序。Vue.js是一个流行的JavaScript框架,用于构建交互式Web界面,而Electron是一个基于Chromium和Node.js的框架,可以将Web技术用于桌面应用程序的开发。使用VueElectron可以使开发人员更轻松地开发功能丰富的桌面应用程序,并且可以同时支持Windows,Mac和Linux等多个平台。 ### 回答2: Vue Electron是一个基于Vue.jsElectron的框架,用于开发跨平台的桌面应用程序。Vue.js是一个流行的JavaScript框架,用于构建用户界面,而Electron是一个允许使用JavaScript、HTML和CSS开发桌面程序的开源框架。 Vue Electron的主要优点是它将Web开发桌面应用程序开发结合在一起。开发者可以使用Vue.js的灵活性和易用性来构建用户界面,然后使用Electron应用程序打包成可在Windows、macOS和Linux等平台上运行的桌面应用程序。 使用Vue Electron,可以利用丰富的Vue生态系统,包括Vue Router和Vuex等插件。开发者可以使用这些插件来管理应用程序的路由和状态,从而更容易地构建复杂的桌面应用程序。 此外,Vue Electron还提供了一些工具和技术,使开发桌面应用程序更加方便。例如,开发者可以使用Electron Builder来快速构建和打包应用程序,也可以使用Electron Debug工具来调试应用程序。另外,还有一些社区提供的插件,用于添加桌面通知、系统托盘和本地文件访问等功能。 总的来说,Vue Electron是一个强大而灵活的框架,可以让开发者使用Vue.js来构建出色的用户界面,并使用Electron应用程序打包成跨平台的桌面应用程序。通过结合VueElectron的优势,Vue Electron能够帮助开发者更轻松地开发出功能丰富、易于维护的桌面应用程序。 ### 回答3: Vue Electron是一种结合了Vue.jsElectron框架的开发工具,用于创建跨平台的桌面应用程序。Vue.js是一种流行的JavaScript框架,用于开发现代的单页面应用程序。而Electron是一个开源的框架,可以利用前技术(HTML、CSS和JavaScript)来构建跨平台的桌面应用程序。Vue Electron将这两种技术结合在一起,提供了一个强大的工具,使开发者能够轻松地使用Vue.js构建用户界面,并通过Electron将其打包为可在不同操作系统上运行的应用程序。 使用Vue Electron可以带来许多优势。首先,Vue.js的简洁语法和响应式数据绑定功能使得构建复杂的用户界面变得简单和高效。而Electron的跨平台特性则允许开发者使用相同的代码库创建可以同时运行在Windows、Mac和Linux等操作系统上的应用程序。 另外,Vue Electron还提供了许多工具和插件,使得开发过程更加便捷,例如vue-cli-plugin-electron-builder插件可以帮助开发者轻松地将Vue.js应用打包成可执行文件,并自动生成安装程序。此外,还有一些其他的插件可以帮助开发实现一些高级功能,比如与本地文件系统的交互、系统托盘功能等。 总之,Vue Electron是一个非常强大的开发工具,它将Vue.jsElectron框架结合在一起,提供了一种便捷的方式来创建跨平台的桌面应用程序。无论你是前开发者还是想要创建一个漂亮、高效的跨平台应用程序的个人或企业,Vue Electron都是一个值得考虑的选择。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

嗬呜阿花

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值