Vue3 + Vite + Element Plus web轉為 Electron 應用,解決無法登錄、隱藏自定義導航欄

如何在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-…