如何在vue3 + Vite + Element Plus搭好的架构下转为 electron应用呢?

 https://www.electronjs.org/zh/docs/latest/官方文档  https://www.electronjs.org/zh/docs/latest/ 

第一步:安装 electron相关依赖

npm install electron electron-builder concurrently cross-env --save-dev

本来想学习electron框架 web如何转 electron框架做个桌面应用,结果卡在了安装依赖有点无语。。。一开始以为是npm安装太慢卡死,然后尝试用淘宝镜像cnpm安装、npm版本升级等等一顿操作,最后是安装成功了,但是npm list electron查看版本信息各种兼容报。。

怀疑是electron版本37.2.6版本太高了,把electron降到22还是各种报错。。。

解决修改镜像源:

npm config edit //打开npm配置文件

在配置文件中添加

electron_mirror=https://cdn.npmmirror.com/binaries/electron/
electron_builder_binaries_mirror=https://npmmirror.com/mirrors/electron-builder-binaries/

添加完成后执行安装命令 :

npm install electron electron-builder concurrently cross-env --save-dev

各种踩坑后总算是安装成功了~

第二步:配置 Electron 主进程

创建 electron文件夹

创建:main.js

const { app, BrowserWindow, Menu, ipcMain } = require('electron')
const path = require('path')let mainWindowfunction createWindow() {mainWindow = new BrowserWindow({ width: 1200,height: 800,webPreferences: {preload: path.join(__dirname, 'preload.js'),nodeIntegration: false,contextIsolation: true}})//创建空菜单 - 菜单栏隐藏但快捷键可用const emptyMenu = Menu.buildFromTemplate([])Menu.setApplicationMenu(emptyMenu)// 修改生产环境加载逻辑
if (process.env.NODE_ENV === 'development') {mainWindow.loadURL('http://localhost:8888') //确保自己的端口一致,不然运行调试或打包无效
} else {// 确保正确加载打包后的文件const indexPath = path.join(__dirname, '../dist/index.html')mainWindow.loadFile(indexPath).catch(err => {console.error('加载失败:', err)// 备用加载方式mainWindow.loadURL(`file://${indexPath}#/`)})
}mainWindow.on('closed', () => {mainWindow = null})
}// 处理渲染进程的快捷键事件
ipcMain.on('reload-app', () => {mainWindow.reload()
})ipcMain.on('toggle-devtools', () => {mainWindow.webContents.toggleDevTools()
})ipcMain.on('force-reload', () => {mainWindow.webContents.reloadIgnoringCache()
})app.on('ready', createWindow)app.on('window-all-closed', () => {if (process.platform !== 'darwin') { app.quit()}
})app.on('activate', () => {if (mainWindow === null) {createWindow()}
})

创建:preload.js

const { contextBridge } = require('electron')contextBridge.exposeInMainWorld('electron', {})

第三步:修改package.json

{"name": "my-vue-electron-app","private": true,"version": "0.0.1","main": "electron/main.js","scripts": {"dev": "concurrently -k \"cross-env NODE_ENV=development vite\" \"cross-env NODE_ENV=development electron .\"","build": "vite build && electron-builder","preview": "vite preview","electron:serve": "electron ."},"build": {"appId": "com.example.myvueelectronapp","productName": "你的管理平台","directories": {"output": "build"},"files": ["dist/**/*","electron/**/*","!node_modules/**/*"],"win": {"target": "nsis","icon": "public/02.ico"},"mac": {"target": "dmg","icon": ""},"linux": {"target": "AppImage","icon": ""}},

注意图标icon格式和规范大小,npm run dev,调试不会影响但是打包会提示报错

第四步:修改 Vite 配置

import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
import path from 'path'export default defineConfig({base: './',server: {open: true,host: "0.0.0.0",https: false,//端口号port: 8082,hmr: true,proxy: {'/api': {target: '0', ws: true,changeOrigin: true,rewrite: (path) => path.replace(/^\/api/, ''),},},},build: {outDir: 'dist',emptyOutDir: true,}
})

第五步: npm run dev 调试

第六步: 打包electron npm run build

完成打包后双击打开调试版本与.exe应用

发现登录后路由无法跳转了,原因是Cookies在桌面无效;我项目toke是存在Cookies里面,造成登录路由无法跳转。。。

解决把存储在Cookies数据存储改成 localStorage或sessionStorage 然后重新登录就ok

第七步:隐藏或重置操作导航栏  https://www.electronjs.org/zh/docs/latest/tutorial/custom-title-bar

1.隐藏导航栏,保留调试效果:

   修改main.js

const { app, BrowserWindow, Menu, ipcMain } = require('electron')
const path = require('path')let mainWindowfunction createWindow() {mainWindow = new BrowserWindow({ width: 1200,height: 800,webPreferences: {preload: path.join(__dirname, 'preload.js'),nodeIntegration: false,contextIsolation: true}})//创建空菜单 - 菜单栏隐藏但快捷键可用const emptyMenu = Menu.buildFromTemplate([])Menu.setApplicationMenu(emptyMenu)// 修改生产环境加载逻辑
if (process.env.NODE_ENV === 'development') {mainWindow.loadURL('http://localhost:8888')
} else {// 确保正确加载打包后的文件const indexPath = path.join(__dirname, '../dist/index.html')mainWindow.loadFile(indexPath).catch(err => {console.error('加载失败:', err)// 备用加载方式mainWindow.loadURL(`file://${indexPath}#/`)})
}mainWindow.on('closed', () => {mainWindow = null})
}// 处理渲染进程的快捷键事件
ipcMain.on('reload-app', () => {mainWindow.reload()
})ipcMain.on('toggle-devtools', () => {mainWindow.webContents.toggleDevTools()
})ipcMain.on('force-reload', () => {mainWindow.webContents.reloadIgnoringCache()
})app.on('ready', createWindow)app.on('window-all-closed', () => {if (process.platform !== 'darwin') { app.quit()}
})app.on('activate', () => {if (mainWindow === null) {createWindow()}
})

   修改preload.js

const { contextBridge, ipcRenderer } = require('electron')// 安全地暴露 API 给渲染进程
contextBridge.exposeInMainWorld('electron', {// 可以在这里添加需要暴露的 API
})// 监听键盘事件
document.addEventListener('keydown', (event) => {// Ctrl/Cmd + R: 刷新if ((event.ctrlKey || event.metaKey) && event.key === 'r') {event.preventDefault()ipcRenderer.send('reload-app')}// F12: 开发者工具if (event.key === 'F12') {event.preventDefault()ipcRenderer.send('toggle-devtools')}// Ctrl/Cmd + Shift + R: 强制刷新if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === 'R') {event.preventDefault()ipcRenderer.send('force-reload')}
})

成功去掉导航栏,快捷键也可调试

2.自定义导航栏名称:

修改main.js

//创建空菜单 命名可根据需求修改const template = [{label: 'File',submenu: [{ role: 'quit' }]},{label: 'Edit',submenu: [{ role: 'undo' },{ role: 'redo' },{ type: 'separator' },{ role: 'cut' },{ role: 'copy' },{ role: 'paste' }]},{label: 'View',submenu: [{ role: 'reload' },{ role: 'forcereload' },{ role: 'toggledevtools' },{ type: 'separator' },{ role: 'resetzoom' },{ role: 'zoomin' },{ role: 'zoomout' },{ type: 'separator' },{ role: 'togglefullscreen' }]}]const emptyMenu = Menu.buildFromTemplate(template)Menu.setApplicationMenu(emptyMenu)

修改preload.js

const { contextBridge, ipcRenderer } = require('electron')contextBridge.exposeInMainWorld('electron', {})// 监听键盘事件
// document.addEventListener('keydown', (event) => {// Ctrl/Cmd + R: 刷新// if ((event.ctrlKey || event.metaKey) && event.key === 'r') {//   event.preventDefault()//   ipcRenderer.send('reload-app')// }// // F12: 开发者工具// if (event.key === 'F12') {//   event.preventDefault()//   ipcRenderer.send('toggle-devtools')// }// // Ctrl/Cmd + Shift + R: 强制刷新// if ((event.ctrlKey || event.metaKey) && event.shiftKey && event.key === 'R') {//   event.preventDefault()//   ipcRenderer.send('force-reload')// }
// })

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/web/96586.shtml
繁体地址,请注明出处:http://hk.pswp.cn/web/96586.shtml
英文地址,请注明出处:http://en.pswp.cn/web/96586.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

qt QAreaLegendMarker详解

1. 概述QAreaLegendMarker 是 Qt Charts 模块中的一部分,用于在图例(Legend)中表示 QAreaSeries 的标记。它负责显示区域图的图例项,通常包含区域颜色样例和对应的描述文字。图例标记和对应的区域图关联,显示区域的名称…

linux 函数 kstrtoul

kstrtoul 函数概述 kstrtoul 是 Linux 内核中的一个函数&#xff0c;用于将字符串转换为无符号长整型&#xff08;unsigned long&#xff09;。该函数定义在 <linux/kernel.h> 头文件中&#xff0c;常用于内核模块中解析用户空间传递的字符串参数。 函数原型 int kstrtou…

LLM(三)

一、人类反馈的强化学习&#xff08;RLHF&#xff09;微调的目标是通过指令&#xff0c;包括路径方法&#xff0c;进一步训练你的模型&#xff0c;使他们更好地理解人类的提示&#xff0c;并生成更像人类的回应。RLHF&#xff1a;使用人类反馈微调型语言模型&#xff0c;使用强…

DPO vs PPO,偏好优化的两条技术路径

1. 背景在大模型对齐&#xff08;alignment&#xff09;里&#xff0c;常见的两类方法是&#xff1a;PPO&#xff1a;强化学习经典算法&#xff0c;OpenAI 在 RLHF 里用它来“用奖励模型更新策略”。DPO&#xff1a;2023 年提出的新方法&#xff08;参考论文《Direct Preferenc…

BLE6.0信道探测,如何重构物联网设备的距离感知逻辑?

在物联网&#xff08;IoT&#xff09;无线通信技术快速渗透的当下&#xff0c;实现人与物、物与物之间对物理距离的感知响应能力已成为提升设备智能高度与人们交互体验的关键所在。当智能冰箱感知用户靠近而主动亮屏显示内部果蔬时、当门禁系统感知到授权人士靠近而主动开门时、…

【计算机 UTF-8 转换为本地编码的含义】

UTF-8 转换为本地编码的含义 详细解释一下"UTF-8转换为本地编码"的含义以及为什么在处理中文时这很重要。 基本概念 UTF-8 编码 国际标准&#xff1a;UTF-8 是一种能够表示世界上几乎所有字符的 Unicode 编码方式跨平台兼容&#xff1a;无论在哪里&#xff0c;UTF-8 …

4.6 变体

1.变体简介 2.为什么需要变体 3.变体是如何产生的 4.变体带来的麻烦 5.multi_compile和shader_feature1.变体简介 比如我们开了一家餐厅, 你有一本万能的菜单(Shader源代码), 上面包含了所有可能的菜式; 但是顾客每次来点餐时, 不可能将整本菜单都做一遍, 他们会根据今天有没有…

猿辅导Android开发面试题及参考答案(下)

为什么开发中要使用线程池,而不是直接创建线程(如控制线程数量、复用线程、降低开销)? 开发中优先使用线程池而非直接创建线程,核心原因是线程池能优化线程管理、降低资源消耗、提高系统稳定性,而直接创建线程存在难以解决的缺陷,具体如下: 控制线程数量,避免资源耗尽…

【网络通信】IP 地址深度解析:从技术原理到企业级应用​

IP 地址深度解析&#xff1a;从技术原理到企业级应用​ 文章目录IP 地址深度解析&#xff1a;从技术原理到企业级应用​前言一、基础认知&#xff1a;IP 地址的技术定位与核心特性​1.1 定义与网络层角色1.2 核心属性与表示法深化二、地址分类&#xff1a;从类别划分到无类别路…

grafana实践

一、如何找到grafana的插件目录 whereis grafana grafana: /etc/grafana /usr/share/grafana插件安装目录、默认安装目录&#xff1a; 把vertamedia-clickhouse-datasource-3.4.4.zip解压到下面目录&#xff0c;然后重启就可以了 /var/lib/grafana/plugins# 6. 设置权限 sudo …

uniapp 文件查找失败:main.js

重装HbuilderX vue.config.js 的 配置 有问题main.js 框架能自动识别 到&#xff0c;不用多余的配置

KEIL烧录时提示“SWD/JTAG communication failure”的解决方法

最新在使用JTAG仿真器串口下载调试程序时&#xff0c;老是下载不成功&#xff0c;识别不到芯片&#xff0c;我尝试重启keil5或者重新插拔仿真器连接线、甚至重启电脑也都不行&#xff0c;每次下载程序都提示如下信息&#xff1a;在确定硬件连接没有问题之后&#xff0c;就开始分…

红日靶场(三)——个人笔记

环境搭建 添加一张网卡&#xff08;仅主机模式&#xff09;&#xff0c;192.168.93.0/24 网段 开启centos&#xff0c;第一次运行&#xff0c;重启网络服务 service network restart192.168.43.57/24&#xff08;外网ip&#xff09; 192.168.93.100/24&#xff08;内网ip&am…

车载网关框架 --- 车内网关IP转CAN链路解析 done

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 做到欲望极简,了解自己的真实欲望,不受外在潮流的影响,不盲从,不跟风。把自己的精力全部用在自己。一是去掉多余,凡事找规律,基础是诚信;二是…

lvgl修改输入设备驱动使其支持鼠标右键、双击、滑轮...

我在前几章移植 lvgl 到linux上时讲过注册鼠标驱动部分&#xff0c;那时候使用的时默认提供的驱动&#xff0c;支持的鼠标功能很少&#xff0c;只有左键点击&#xff0c;那时候我提过我们可以修改驱动使其支持&#xff0c;下面是具体的实现。看上面代码&#xff0c;我们当时是直…

SpringBoot 中单独一个类中运行main方法报错:找不到或无法加载主类

1. 报错SpringBoot项目&#xff0c;在随机某个类使用main方法&#xff0c;点击运行/调试报错错误: 找不到或无法加载主类 com.central.workorder.config.PropertyEncrypt 原因: java.lang.ClassNotFoundException: com.central.workorder.config.PropertyEncrypt2. 原因缩短命令…

React 核心 Hook 与冷门技巧:useReducer、useEffect、useRef 及 is 属性全解析

&#x1f4da; 前言React 的函数组件 Hooks 模式已经成为现代前端开发的主流。相比类组件&#xff0c;Hooks 让状态管理和副作用处理更加简洁和可复用。但在实际开发中&#xff0c;除了常用的 useState 和 useEffect&#xff0c;还有很多“进阶武器”值得我们掌握。本文将深入…

通义灵码产品演示: 数据库设计与数据分析

作者&#xff1a;了哥 演示主题&#xff1a;AI 进行数据库设计以及做数据分析 演示目的 演示通义灵码对于数据库的设计能力以及数据分析能力。 演示准备 准备数据库&#xff0c;这里为了简单实用 sqlite3 brew install sqlite3使用 vscode&#xff0c;同时安装好通义灵码的插件…

MySQL主从同步参数调优案例

#作者&#xff1a;stackofumbrella 文章目录一、前言二、故障概述2.1 基础信息2.2 故障现象描述三、故障诊断分析3.1 排查过程3.2 问题根因四、故障解决方案 &#x1f4ca;4.1 解决方案 &#x1f6e0;️五、总结附件一、前言 在磐基系统中大量使用MySQL作为后端的数据存储&…

【代码随想录算法训练营——Day10】栈与队列——232.用栈实现队列、225.用队列实现栈、20.有效的括号、1047.删除字符串中的所有相邻重复项

LeetCode题目链接 https://leetcode.cn/problems/implement-queue-using-stacks/ https://leetcode.cn/problems/implement-stack-using-queues/description/ https://leetcode.cn/problems/valid-parentheses/description/ https://leetcode.cn/problems/remove-all-adjacent-…