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

news2025/6/3 5:11:48

预览

请添加图片描述

开源项目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 this
  webPreferences: {
    sandbox: false // <-- to be able to import @electron/remote in preload script
    // ...
  }
})

enable(mainWindow.webContents) // <-- add this

mainWindow.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 mainWindow

async function createWindow () {
  /**
   * Initial window options
   */
  mainWindow = new BrowserWindow({
    icon: path.resolve(currentDir, 'icons/icon.png'), // tray icon
    width: 1200,
    height: 900,
    useContentSize: true,
    frame: false,
    webPreferences: {
      sandbox: false, // 开启沙盒则preload脚本被禁用,所以得设为false
      contextIsolation: true,
      // More info: https://v2.quasar.dev/quasar-cli-vite/developing-electron-apps/electron-preload-script
      preload: path.resolve(
        currentDir,
        path.join(process.env.QUASAR_ELECTRON_PRELOAD_FOLDER, 'electron-preload' + process.env.QUASAR_ELECTRON_PRELOAD_EXTENSION)
      )
    }
  })

  enable(mainWindow.webContents) // <-- add this

  if (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 enabled
    mainWindow.webContents.openDevTools()
  } else {
    // we're on production; no access to devtools pls
    mainWindow.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.coloradmin.cn/o/2395003.html

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

相关文章

【HW系列】—Windows日志与Linux日志分析

文章目录 一、Windows日志1. Windows事件日志2. 核心日志类型3. 事件日志分析实战详细分析步骤 二、Linux日志1. 常见日志文件2. 关键日志解析3. 登录爆破检测方法日志分析核心要点 一、Windows日志 1. Windows事件日志 介绍&#xff1a;记录系统、应用程序及安全事件&#x…

VIN码识别解析接口如何用C#进行调用?

一、什么是VIN码识别解析接口&#xff1f; VIN码不仅是车辆的“身份证”&#xff0c;更是连接制造、销售、维修、保险、金融等多个环节的数字纽带。而VIN码查询API&#xff0c;正是打通这一链条的关键工具。 无论是汽车电商平台、二手车商、维修厂&#xff0c;还是保险公司、金…

动态规划之网格图模型(一)

文章目录 动态规划之网格图模型&#xff08;一&#xff09;LeetCode 64. 最小路径和思路Golang 代码 LeetCode 62. 不同路径思路Golang 代码 LeetCode 63. 不同路径 II思路Golang 代码 LeetCode 120. 三角形最小路径和思路Golang 代码 LeetCode 3393. 统计异或值为给定值的路径…

PCB设计实践(三十)地平面完整性

在高速数字电路和混合信号系统设计中&#xff0c;地平面完整性是决定PCB性能的核心要素之一。本文将从电磁场理论、信号完整性、电源分配系统等多个维度深入剖析地平面设计的关键要点&#xff0c;并提出系统性解决方案。 一、地平面完整性的电磁理论基础 电流回流路径分析 在PC…

使用ray扩展python应用之流式处理应用

流式处理就是数据一来&#xff0c;咱们就得赶紧处理&#xff0c;不能攒批再算。这里的实时不是指瞬间完成&#xff0c;而是要在数据产生的那一刻&#xff0c;或者非常接近那个时间点&#xff0c;就做出响应。这种处理方式&#xff0c;我们称之为流式处理。 流式处理的应用场景…

IP证书的作用与申请全解析:从安全验证到部署实践

在网络安全领域&#xff0c;IP证书&#xff08;IP SSL证书&#xff09;作为传统域名SSL证书的补充方案&#xff0c;专为公网IP地址提供HTTPS加密与身份验证服务。本文将从技术原理、应用场景、申请流程及部署要点四个维度&#xff0c;系统解析IP证书的核心价值与操作指南。 一…

【Linux系列】Linux/Unix 系统中的 CPU 使用率

博客目录 多核处理器时代的 CPU 使用率计算为什么要这样设计&#xff1f; 解读实际案例&#xff1a;268.76%的 CPU 使用率性能分析的意义 相关工具与监控实践1. top 命令2. htop 命令3. mpstat 命令4. sar 命令 实际应用场景容量规划性能调优故障诊断 深入理解&#xff1a;CPU …

C++语法系列之模板进阶

前言 本次会介绍一下非类型模板参数、模板的特化(特例化)和模板的可变参数&#xff0c;不是最开始学的模板 一、非类型模板参数 字面意思,比如&#xff1a; template<size_t N 10> 或者 template<class T,size_t N 10>比如&#xff1a;静态栈就可以用到&#…

基于图神经网络的自然语言处理:融合LangGraph与大型概念模型的情感分析实践

在企业数字化转型进程中&#xff0c;非结构化文本数据的处理与分析已成为核心技术挑战。传统自然语言处理方法在处理客户反馈、社交媒体内容和内部文档等复杂数据集时&#xff0c;往往难以有效捕获文本间的深层语义关联和结构化关系。大型概念模型&#xff08;Large Concept Mo…

R 语言科研绘图 --- 热力图-汇总

在发表科研论文的过程中&#xff0c;科研绘图是必不可少的&#xff0c;一张好看的图形会是文章很大的加分项。 为了便于使用&#xff0c;本系列文章介绍的所有绘图都已收录到了 sciRplot 项目中&#xff0c;获取方式&#xff1a; R 语言科研绘图模板 --- sciRplothttps://mp.…

解决访问网站提示“405 很抱歉,由于您访问的URL有可能对网站造成安全威胁,您的访问被阻断”问题

一、问题描述 本来前几天都可以正常访问的网站&#xff0c;但是今天当我们访问网站的时候会显示“405 很抱歉&#xff0c;由于您访问的URL有可能对网站造成安全威胁&#xff0c;您的访问被阻断。您的请求ID是&#xff1a;XXXX”&#xff0c;而不能正常的访问网站&#xff0c;如…

机器学习中的关键术语及其含义

神经元及神经网络 机器学习中的神经网络是一种模仿生物神经网络的结构和功能的数学模型或计算模型。它是指按照一定的规则将多个神经元连接起来的网络。 神经网络是一种运算模型&#xff0c;由大量的节点&#xff08;或称神经元&#xff09;之间相互联接构成。每个节点代表一…

网络编程1_网络编程引入

为什么需要网络编程&#xff1f; 用户再在浏览器中&#xff0c;打开在线视频资源等等&#xff0c;实质上说通过网络&#xff0c;获取到从网络上传输过来的一个资源。 与打开本地的文件类似&#xff0c;只是这个文件的来源是网络。相比本地资源来说&#xff0c;网络提供了更为…

【Day38】

DAY 38 Dataset和Dataloader类 对应5. 27作业 知识点回顾&#xff1a; Dataset类的__getitem__和__len__方法&#xff08;本质是python的特殊方法&#xff09;Dataloader类minist手写数据集的了解 作业&#xff1a;了解下cifar数据集&#xff0c;尝试获取其中一张图片 import …

HTML Day04

Day04 0.引言1. HTML字符实体2. HTML表单2.1 表单标签2.2 表单示例 3. HTML框架4. HTML颜色4.1 16进制表示法4.2 rgba表示法4.3 名称表达法 5. HTML脚本 0.引言 刚刚回顾了前面几篇博客&#xff0c;感觉写的内容倒是很详细&#xff0c;每个知识点都做了说明。但是感觉在知识组织…

云原生安全基石:Kubernetes 核心概念与安全实践指南

&#x1f525;「炎码工坊」技术弹药已装填&#xff01; 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. Kubernetes 架构全景 Kubernetes&#xff08;简称 K8s&#xff09;采用主从架构&#xff0c;由控制平面&#xff08;Control Plane&…

autodl 安装了多个conda虚拟环境 选择合适虚拟环境的语句

1.conda env list 列出所有虚拟环境 可以看到&#xff0c;我有两个虚拟环境&#xff0c;一个是joygen&#xff0c;一个是base conda activate base 或者 conda activate joygen 激活对应的环境。我选择激活 joygen 环境 然后就可以在joygen环境下进行操作了 base环境也是同理…

ansible-playbook 进阶 接上一章内容

1.异常中断 做法1&#xff1a;强制正常 编写 nginx 的 playbook 文件 01-zuofa .yml - hosts : web remote_user : root tasks : - name : create new user user : name nginx-test system yes uid 82 shell / sbin / nologin - name : test new user shell : gete…

趋势直线指标

趋势直线副图和主图指标&#xff0c;旨在通过技术分析工具帮助交易者识别市场趋势和潜在的买卖点。 副图指标&#xff1a;基于KDJ指标的交易策略 1. RSV值计算&#xff1a; - RSV&#xff08;未成熟随机值&#xff09;反映了当前收盘价在过去一段时间内的相对位置。通过计算当前…

基线配置管理:为什么它对网络稳定性至关重要

什么是基线配置&#xff08;Baseline Configuration&#xff09; 基线配置&#xff08;Baseline Configuration&#xff09;是经过批准的标准化主设置&#xff0c;代表所有设备应遵循的安全、合规且运行稳定的配置基准&#xff0c;可作为评估变更、偏差或未授权修改的参考基准…