当前位置: 首页 > news >正文

quasar electron mode如何打包无边框桌面应用程序

预览

请添加图片描述

开源项目Tokei Kun

一款简洁的周年纪念app,现已发布APK(安卓)和 EXE(Windows)
项目仓库地址:Github Repo
应用下载链接:Github Releases

Preparation for Electron

quasar dev -m electron# passing extra parameters and/or options to
# underlying "electron" executable:
quasar dev -m electron -- --no-sandbox --disable-setuid-sandbox
# when on Windows and using Powershell:
quasar dev -m electron '--' --no-sandbox --disable-setuid-sandbox

基本命令

quasar dev -m electron

指定以 Electron 模式运行启动 Quasar 开发服务器

传递参数

Linux/MacOS 语法:

quasar dev -m electron -- --no-sandbox --disable-setuid-sandbox
  • --: 这个符号表示后面的参数是传递给底层 Electron 可执行文件的,而不是 Quasar CLI

Windows PowerShell 语法:

quasar dev -m electron '--' --no-sandbox --disable-setuid-sandbox
  • 在 PowerShell 中需要用引号包裹 --

参数解释

–no-sandbox

禁用 Chromium 的沙盒(sandbox)安全机制沙盒是一种安全功能,限制应用程序对系统资源的访问禁用沙盒可能会降低安全性,但在某些环境下是必要的

–disable-setuid-sandbox

禁用 setuid 沙盒setuid 是一种 Unix 权限机制,允许程序以更高权限运行,在某些 Linux 系统上,如果无法使用 setuid 沙盒,需要禁用此功能

Frameless Electron Window

安装依赖

npm install --save @electron/remote

修改electron-main.js

import { app, BrowserWindow, nativeTheme } from 'electron'
import { initialize, enable } from '@electron/remote/main' // <-- add this
import path from 'path'initialize() // <-- add this// ...mainWindow = new BrowserWindow({width: 1000,height: 600,useContentSize: true,frame: false // <-- add thiswebPreferences: {sandbox: false // <-- to be able to import @electron/remote in preload script// ...}
})enable(mainWindow.webContents) // <-- add thismainWindow.loadURL(process.env.APP_URL)// ...

[!warning]
官方文档中import { initialize, enable } from ‘@electron/remote/main’
这里我出现了报错
改为import { initialize, enable } from '@electron/remote/main/index.js’正常运行

![[import error.png]]
quasar issue:Electron dev app @electron/remote error · Issue #17971 · quasarframework/quasar

[!success] 成功
接下里我们需要处理窗口拖拽以及最小化、最大化与关闭应用

预加载脚本

由于我们无法直接从渲染线程访问 Electron,需要通过 electron 预加载脚本( src-electron/main-process/electron-preload.js )提供必要功能。因此我们将其修改为:

//src-electron/main-process/electron-preload
import { contextBridge } from 'electron'
import { BrowserWindow } from '@electron/remote'contextBridge.exposeInMainWorld('myWindowAPI', {minimize () {BrowserWindow.getFocusedWindow().minimize()},toggleMaximize () {const win = BrowserWindow.getFocusedWindow()if (win.isMaximized()) {win.unmaximize()} else {win.maximize()}},close () {BrowserWindow.getFocusedWindow().close()}
})

处理窗口拖拽

当我们使用无边框窗口(仅限无边框!)时,还需要为用户提供在屏幕上移动应用窗口的方式。为此,您可以使用 q-electron-dragq-electron-drag--exception Quasar CSS 辅助类。

[!TIPS] 提示
也许你可以在layout文件中为某些组件添加类q-electron-drag试试

该功能允许用户在屏幕上点击、按住并同时拖动鼠标时,拖拽应用程序窗口。

最小化、最大化与关闭应用

在某些vue文件(例如添加在MainLayout.vue中)
Template

<q-space /><q-btn dense flat icon="minimize" @click="minimize" />
<q-btn dense flat icon="crop_square" @click="toggleMaximize" />
<q-btn dense flat icon="close" @click="closeApp" />

[!TIP]
若觉得iconminimize不太习惯(位于底部),可以使用remove(竖直居中)
q-space的作用是将q-btn挤到右边

选项式

<script>
// We guard the Electron API calls with the optional chaining JS operator,
// but this is only needed if we build same app with other Quasar Modes
// as well (SPA/PWA/Cordova/SSR...)export default {setup () {function minimize () {window.myWindowAPI?.minimize()}function toggleMaximize () {window.myWindowAPI?.toggleMaximize()}function closeApp () {window.myWindowAPI?.close()}return { minimize, toggleMaximize, closeApp }}
}
</script>

组合式

<script setup>
// We guard the Electron API calls with the optional chaining JS operator,
// but this is only needed if we build same app with other Quasar Modes
// as well (SPA/PWA/Cordova/SSR...)function minimize() {if (process.env.MODE === 'electron') {window.myWindowAPI?.minimize()}
}function toggleMaximize() {if (process.env.MODE === 'electron') {window.myWindowAPI?.toggleMaximize()}
}function closeApp() {if (process.env.MODE === 'electron') {window.myWindowAPI?.close()}
}
</script>

Electron的 Unable to load preload script 报错解决方案-CSDN博客

Build

quasar build -m electron -d

附完整代码

electron-main.js

import { app, BrowserWindow, ipcMain } from 'electron'
import { initialize, enable } from '@electron/remote/main/index.js' // <-- add this
import path from 'node:path'
import os from 'node:os'
import { fileURLToPath } from 'node:url'initialize() // <-- add this
// needed in case process is undefined under Linux
const platform = process.platform || os.platform()const currentDir = fileURLToPath(new URL('.', import.meta.url))let mainWindowasync function createWindow () {/*** Initial window options*/mainWindow = new BrowserWindow({icon: path.resolve(currentDir, 'icons/icon.png'), // tray iconwidth: 1200,height: 900,useContentSize: true,frame: false,webPreferences: {sandbox: false, // 开启沙盒则preload脚本被禁用,所以得设为falsecontextIsolation: true,// More info: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/electron-preload-scriptpreload: path.resolve(currentDir,path.join(process.env.QUASAR_ELECTRON_PRELOAD_FOLDER, 'electron-preload' + process.env.QUASAR_ELECTRON_PRELOAD_EXTENSION))}})enable(mainWindow.webContents) // <-- add thisif (process.env.DEV) {await mainWindow.loadURL(process.env.APP_URL)} else {await mainWindow.loadFile('index.html')}if (process.env.DEBUGGING) {// if on DEV or Production with debug enabledmainWindow.webContents.openDevTools()} else {// we're on production; no access to devtools plsmainWindow.webContents.on('devtools-opened', () => {mainWindow.webContents.closeDevTools()})}mainWindow.on('closed', () => {mainWindow = null})
}app.whenReady().then(createWindow)app.on('window-all-closed', () => {if (platform !== 'darwin') {app.quit()}
})app.on('activate', () => {if (mainWindow === null) {createWindow()}
})

electron-preload.js

import { contextBridge } from 'electron'
import { BrowserWindow } from '@electron/remote/'contextBridge.exposeInMainWorld('myWindowAPI', {minimize () {BrowserWindow.getFocusedWindow().minimize()},toggleMaximize () {const win = BrowserWindow.getFocusedWindow()if (win.isMaximized()) {win.unmaximize()} else {win.maximize()}},close () {BrowserWindow.getFocusedWindow().close()}
})
/*** This file is used specifically for security reasons.* Here you can access Nodejs stuff and inject functionality into* the renderer thread (accessible there through the "window" object)** WARNING!* If you import anything from node_modules, then make sure that the package is specified* in package.json > dependencies and NOT in devDependencies** Example (injects window.myAPI.doAThing() into renderer thread):**   import { contextBridge } from 'electron'**   contextBridge.exposeInMainWorld('myAPI', {*     doAThing: () => {}*   })** WARNING!* If accessing Node functionality (like importing @electron/remote) then in your* electron-main.js you will need to set the following when you instantiate BrowserWindow:** mainWindow = new BrowserWindow({*   // ...*   webPreferences: {*     // ...*     sandbox: false // <-- to be able to import @electron/remote in preload script*   }* }*/

相关文章:

  • 代码随想录算法训练营 Day60 图论Ⅹ Bellmen_ford 系列算法
  • 由反汇编代码确定结构体的完整声明
  • 精通 Kubernetes:从故障排除到化繁为简
  • Eclipse集成lombok
  • 数据结构之队列:原理与应用
  • 嵌入式(1):STM32 GPIO与AFIO深度解析:从原理到高阶应用实战
  • ES分词搜索
  • QT- QML Layout+anchors 布局+锚点实现窗口部件自适应比例
  • 使用 `\033` 方式设置终端字体颜色
  • JavaSwing之--JPasswordField
  • 电机试验平台:现代科技与工程应用的典范
  • 如何把TikTok的视频下载到本地?
  • Transformer时间序列预测
  • PDF文件转换之输出指定页到新的 PDF 文件
  • 封装一个Qt调用动态库的类
  • 【C++】位图
  • QPS 和 TPS 详解
  • 理想树图书:以科技赋能教育,开启AI时代自主学习新范式
  • spring切面
  • 三格电子——如何解决消防设备联网问题
  • 如何做线上赌博的网站/bt搜索引擎最好用的
  • 怎样建设博彩网站/品牌宣传推广方案
  • ai效果图网站/查询网站相关网址
  • 建站公司哪家好 知道万维科技/网络营销模式有哪些类型
  • 男生可以做网站编辑工作吗/深圳网络营销外包公司推荐
  • php智能建站系统/网站seo哪家做的好