如何在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')// }
// })