如何在vue3 + Vite + Element Plus搭好的架构下转为 electron应用呢?
第一步:安装 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 mainWindow
function 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
第七步:隐藏或重置操作导航栏
1.隐藏导航栏,保留调试效果:
修改main.js
const { app, BrowserWindow, Menu, ipcMain } = require('electron')
const path = require('path')
let mainWindow
function 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.自定义导航栏名称: