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*   }* }*/

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

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

相关文章

微信小程序真机调试时如何实现与本地开发环境服务器交互

最近在开发微信小程序项目,真机调试时需要在手机上运行小程序,为了实现本地开发服务器与手机小程序的交互,需要以下步骤 1.将手机连到和本地一样的局域网 2.Visual Studio中将IIS Express服务器的localhost端口地址修改为本机的IP自定义的端口: 1&#xff09;找到web api项目…

Scratch节日 | 拯救屈原 | 端午节

端午节快乐&#xff01; 这款特别为端午节打造的Scratch游戏 《拯救屈原》&#xff0c;将带你走进古代中国&#xff0c;感受历史与文化的魅力&#xff01; &#x1f3ee; 游戏介绍 扮演勇敢的探险者&#xff0c;穿越时空回到古代&#xff0c;解锁谜题&#xff0c;完成任务&…

PHP下实现RSA的加密,解密,加签和验签

前言&#xff1a; RSA下加密&#xff0c;解密&#xff0c;加签和验签是四种不同的操作&#xff0c;有时候会搞错&#xff0c;记录一下。 1.公钥加密&#xff0c;私钥解密 发送方通过公钥将原数据加密成一个sign参数&#xff0c;相当于就是信息的载体&#xff0c;接收方能通过si…

Win10秘笈:两种方式修改网卡物理地址(MAC)

Win10秘笈&#xff1a;两种方式修改网卡物理地址&#xff08;MAC&#xff09; 在修改之前&#xff0c;可以先确定一下要修改的网卡MAC地址&#xff0c;查询方法有很多种&#xff0c;比如&#xff1a; 1、在设置→网络和Internet→WLAN/以太网&#xff0c;如下图所示。 2、在控…

C++中IO文件输入输出知识详解和注意事项

以下内容将从文件流类体系、打开模式、文本与二进制 I/O、随机访问、错误处理、性能优化等方面&#xff0c;详解 C 中文件输入输出的使用要点&#xff0c;并配以示例。 一、文件流类体系 C 标准库提供三种文件流类型&#xff0c;均定义在 <fstream> 中&#xff1a; std…

Unity3D仿星露谷物语开发56之保存角色位置到文件

1、目标 游戏中通过Save Game保存角色位置&#xff0c;当重启游戏后&#xff0c;通过Load Game可以恢复角色的位置。 2、Player对象操作 &#xff08;1&#xff09;组件添加 给Hierarchy下的Player组件添加Generate GUID组件。 &#xff08;2&#xff09;修改SceneSave.cs脚…

TKernel模块--杂项

TKernel模块–杂项 1.DEFINE_HARRAY1 #define DEFINE_HARRAY1(HClassName, _Array1Type_) \ class HClassName : public _Array1Type_, public Standard_Transient { \public: …

c++ typeid运算符

typeid运算符能获取类型信息。获取到的是type_info对象。type_info类型如下&#xff1a; 可以看到&#xff0c;这个类删除了拷贝构造函数以及等号操作符。有一些成员函数&#xff1a;hash_code、before、name、raw_name, 还重载了和!运算符。 测试&#xff1a; void testTyp…

第304个Vulnhub靶场演练攻略:digital world.local:FALL

digital world.local&#xff1a;FALL Vulnhub 演练 FALL (digitalworld.local: FALL) 是 Donavan 为 Vulnhub 打造的一款中型机器。这款实验室非常适合经验丰富的 CTF 玩家&#xff0c;他们希望在这类环境中检验自己的技能。那么&#xff0c;让我们开始吧&#xff0c;看看如何…

【数据库】数据库恢复技术

数据库恢复技术 实现恢复的核心是使用冗余&#xff0c;也就是根据冗余数据重建不正确数据。 事务 事务是一个数据库操作序列&#xff0c;是一个不可分割的工作单位&#xff0c;是恢复和并发的基本单位。 在关系数据库中&#xff0c;一个事务是一条或多条SQL语句&#xff0c…

switch-case判断

switch-case判断 #include <stdio.h> int main() {int type;printf("请输入你的选择&#xff1a;\n");scanf("%d",&type);getchar();switch (type){case 1:printf("你好&#xff01;");break;case 2:printf("早上好&#xff01;…

从监控到告警:Prometheus+Grafana+Alertmanager+告警通知服务全链路落地实践

文章目录 一、引言1.1 监控告警的必要性1.2 监控告警的基本原理1.2.1 指标采集与存储1.2.2 告警规则与触发机制1.2.3 多渠道通知与闭环 二、技术选型与架构设计2.1 为什么选择 Prometheus 及其生态2.1.1 Prometheus 优势分析2.1.2 Grafana 可视化能力2.1.3 Alertmanager 灵活告…

STM32 UART通信实战指南:从原理到项目落地

STM32串口通信实战指南&#xff1a;从零开始手把手教你 前言&#xff1a;为什么串口这么重要&#xff1f; 在嵌入式开发中&#xff0c;串口就像设备的"嘴巴"和"耳朵"。无论是给单片机下达指令、读取传感器数据&#xff0c;还是让两个模块"对话"…

Jmeter requests

1.Jemter元件和组件 1.1 元件和组件的概念 元件&#xff1a;多个功能相似的的组件的容器&#xff0c;类似于一个工具箱。 组件&#xff1a;实现某个特定功能的实例&#xff0c;类似于工具箱中的螺丝刀&#xff0c;十字扳手... 1.2 作用域和执行顺序 1.2.1 作用域 例子&#…

计算机视觉---GT(ground truth)

在计算机视觉&#xff08;Computer Vision, CV&#xff09;领域&#xff0c;Ground Truth&#xff08;GT&#xff0c;中文常译为“真值”或“ ground truth”&#xff09; 是指关于数据的真实标签或客观事实&#xff0c;是模型训练、评估和验证的基准。它是连接算法与现实世界的…

1-Wire 一线式总线:从原理到实战,玩转 DS18B20 温度采集

引言 在嵌入式系统中&#xff0c;通信总线是连接 CPU 与外设的桥梁。从 I2C、SPI 到 UART&#xff0c;每种总线都有其独特的应用场景。而本文要介绍的1-Wire 一线式总线&#xff0c;以其极简的硬件设计和独特的通信协议&#xff0c;在温度采集、身份识别等领域大放异彩。本文将…

基于开源AI大模型AI智能名片S2B2C商城小程序源码的销售环节数字化实现路径研究

摘要&#xff1a;在数字化浪潮下&#xff0c;企业销售环节的转型升级已成为提升竞争力的核心命题。本文基于清华大学全球产业研究院《中国企业数字化转型研究报告&#xff08;2020&#xff09;》提出的“提升销售率与利润率、打通客户数据、强化营销协同、构建全景用户画像、助…

Linux浅谈

Linux浅谈 一、什么是 Linux&#xff1f;先抛开 “内核”&#xff0c;看整体 可以把 Linux 系统 想象成一台 “组装电脑”&#xff1a; 最核心的零件是 “主板”—— 这就是 Linux 内核&#xff08;Kernel&#xff09;&#xff0c;负责管理电脑里的所有硬件&#xff08;比如 …

PostgreSQL ERROR: out of shared memory处理

使用pg_dump命令导出一个库的时候&#xff0c;报 pg_dump: error: query failed: ERROR: out of shared memory HINT: You might need to increase "max_locks_per_transaction". 从错误字面上看是超出内存大小了&#xff0c;建议增加max_locks_per_transaction参…

IoT/基于NB28-A/BC28-CNV通信模组使用AT指令连接华为云IoTDA平台(HCIP-IoT实验2)

文章目录 概述检查通信环境通信模组固件信号强度CGATT指令参数 / 啥是PS域&#xff1f;PS附着状态&#xff1a;ATCGATTPLMN 选择&#xff1a;ATCOPSCEREG指令参数 / 啥是EPS与EPC?CEREG指令参数 / 啥是URC?网络注册状态&#xff1a;ATCEREG网络附着和网络注册 AT指令接入IoTD…