惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Exploit Database - CXSecurity.com
J
Java Code Geeks
H
Help Net Security
B
Blog RSS Feed
G
Google Developers Blog
博客园 - 司徒正美
MongoDB | Blog
MongoDB | Blog
量子位
博客园 - 三生石上(FineUI控件)
The Cloudflare Blog
P
Proofpoint News Feed
小众软件
小众软件
人人都是产品经理
人人都是产品经理
云风的 BLOG
云风的 BLOG
V
V2EX
月光博客
月光博客
C
Check Point Blog
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
A
Arctic Wolf
Help Net Security
Help Net Security
Schneier on Security
Schneier on Security
D
DataBreaches.Net
酷 壳 – CoolShell
酷 壳 – CoolShell
博客园_首页
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
P
Palo Alto Networks Blog
T
Tenable Blog
L
LangChain Blog
Attack and Defense Labs
Attack and Defense Labs
Google DeepMind News
Google DeepMind News
N
News and Events Feed by Topic
Forbes - Security
Forbes - Security
F
Fortinet All Blogs
Recent Announcements
Recent Announcements
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
大猫的无限游戏
大猫的无限游戏
www.infosecurity-magazine.com
www.infosecurity-magazine.com
Y
Y Combinator Blog
WordPress大学
WordPress大学
Stack Overflow Blog
Stack Overflow Blog
V
Visual Studio Blog
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
Engineering at Meta
Engineering at Meta
NISL@THU
NISL@THU
GbyAI
GbyAI
博客园 - Franky
S
Secure Thoughts
有赞技术团队
有赞技术团队
PCI Perspectives
PCI Perspectives
U
Unit 42

掘墓人的小铲子

新玩意:一加 15 | 掘墓人的小铲子 AI 编程初体验:Trae 帮我写代码 | 掘墓人的小铲子 微信内访问网站提示“非微信官方网页,请确认是否继续访问” | 掘墓人的小铲子 薅羊毛网站 | 掘墓人的小铲子 微信红包封面 | 掘墓人的小铲子 日本东京见闻 | 掘墓人的小铲子 新玩意:奥海 140W 氮化镓青春版充电器 | 掘墓人的小铲子 新玩意:云鲸智能洗地机 F1 冠军版 | 掘墓人的小铲子 新玩意:Windows Hello 指纹识别器 | 掘墓人的小铲子 电脑死机问题排查 | 掘墓人的小铲子 新玩意:WESCOM 31.5 英寸 4K 显示器 文章被“抄袭”了 | 掘墓人的小铲子 新玩意:乐歌 E2 升降桌 | 掘墓人的小铲子 香港一日游 | 掘墓人的小铲子 跨平台开发之 Tauri | 掘墓人的小铲子 三星 Note4 超级省电模式之 Kindle 看书 博客升级 | 掘墓人的小铲子 使用 Jpom 自动构建和部署项目 | 掘墓人的小铲子 新冠肺炎症状记录 | 掘墓人的小铲子 开源数据备份工具 Duplicati | 掘墓人的小铲子 使用 NotionNext+Notion+Vercel 部署我的木刻网站 | 掘墓人的小铲子 使用 Vercel 快速部署前端项目 | 掘墓人的小铲子 企业共享办公好助手:可道云 kodbox | 掘墓人的小铲子 新玩意|一加 Ace Pro | 掘墓人的小铲子 使用 Photo Stream 部署相册 | 掘墓人的小铲子 新玩意|罗技 MX Master 3 鼠标 2021 年终总结 | 掘墓人的小铲子 新玩意|Bcase 数据线磁吸收纳器 | 掘墓人的小铲子 我的习惯养成计划:五分钟规则+打卡 | 掘墓人的小铲子 我用66张照片记录过去一年做过的饭菜 | 掘墓人的小铲子 送你一个虎年红包封面:虎虎生威 | 掘墓人的小铲子 新玩意|海氏K3空气炸锅烤箱 | 掘墓人的小铲子 新玩意|Yeelight易来 智能人体感应灯小夜灯 | 掘墓人的小铲子 超稳的高颜值支架:海备思铝合金手机支架 | 掘墓人的小铲子 没有了无限免费存储空间,谷歌相册还能继续用吗? | 掘墓人的小铲子 置物架改造 | 掘墓人的小铲子 信用卡还款宽限期 | 掘墓人的小铲子 Nginx 开启 gzip 压缩 | 掘墓人的小铲子 记一次意外割手 | 掘墓人的小铲子 Kindle 售后换新记 | 掘墓人的小铲子 记一次麻烦的银行办卡经历 | 掘墓人的小铲子 记一次差点被集中隔离的回家之旅 | 掘墓人的小铲子 自己动手做置物架 | 掘墓人的小铲子 2020 年终总结 | 掘墓人的小铲子 自己动手部署内网穿透:frp | 掘墓人的小铲子 免费内网穿透服务推荐 | 掘墓人的小铲子 怎么提醒女朋友给手机充电? | 掘墓人的小铲子 阿里云盘和 Teambition 网盘 | 掘墓人的小铲子 记一次成功的网购维权:我在 12315 投诉天猫超市 | 掘墓人的小铲子
跨平台开发之 Quasar | 掘墓人的小铲子
2023-04-30 · via 掘墓人的小铲子

开源 跨平台 Electron Quasar Capacitor

使用 Quasar 可以真正做到一次编码,全平台客户端覆盖。

上一篇文章「跨平台开发之 Tauri」,主要记录了桌面端应用的跨平台开发,这次要记录的框架 Quasar 比 Tauri 更强大,不仅能开发桌面端应用,还支持手机 App 和网页端等。

需求

我的需求是这样的,做一个跨平台的软件,至少要有手机端、电脑端和网页端,类似于一个网盘,可以上传文件或文本。

之所以要做这样一个软件,是因为以下两种使用场景:

  • 要给旧手机分享文件或配置文本
  • 临时使用一台电脑,需要安装软件或者登录网站

为什么不使用微信或者网盘呢?

  • 微信不够轻量级,在旧手机上可能带不动或者很慢
  • 网盘下载文件一般都需要安装客户端,临时下载文件不想装客户端

那为什么要做手机端、电脑端和网页端呢?

  • 在手机上使用客户端要比网页体验更好
  • 电脑端是给主力电脑使用,用于文件上传,如果无法实现客户端网页端也可以
  • 网页端是给临时要下载文件或者传输文本的电脑使用,用完即走

又是跨平台开发,那么选什么框架呢?

框架选择

本来想考虑一下 Tauri 的,但是支持手机客户端的版本 2.0 还是 Alpha 版,只好寻找其他框架。

uni-app

首先想到的是 uni-app,uni-app 号称能够「一套代码编到14个平台」,除了 Android、iOS 和 Web,还有一众的小程序。

uni-app

在尝试编码的过程中,我发现了 uni-app 的两个问题。一是生成的 Android 安装包比较大,初始体积就在十几兆。最致命的是第二个问题,通过 npm 安装的包在客户端上会报错。

尝试解决无果后,只好再次寻找其他框架。

官方仓库:https://github.com/quasarframework/quasar

在搜索其他框架的时候,我多次看到了「Quasar」。回想起来我自己的收藏里好像也有这个,但当时看到 Quasar 网站的时候感觉有点不够亮眼,就直接跳过了。

Quasar

入门视频

在没有其他可选框架的情况下,我抱着尝试的心态,打开了 「Why Quasar」 的介绍视频,结果发现进入了新大陆。

视频展示了如何在半小时内制作一个 TODO 应用,并且可以在 Android、iOS、Mac、Windows 和网页上使用。看视频的第一眼我就被 Quasar 开发出的软件界面给吸引了,居然可以做出如此优美的界面,差点就被 Quasar 不够吸引人的网站给迷惑了。

quasar to do app

quasar to do desktop app

quasar to do web

推荐初学者先看一下入门视频「Create an App for Android, iOS, Mac & Windows - in 30 MINUTES!」,如果无法访问可以下载网盘中的视频和字幕进行查看,链接: https://pan.baidu.com/s/12xcGb-J_-03v3lEBrdmOwg ,提取码: zhh2。

为什么要选择 Quasar

之所以选择 Quasar,对我个人而言,有以下两点:

  • 开箱即用的 UI 组件,遵循 Material Design
  • 支持生成 SPA、SSR、PWA、BEX、手机 App 和跨平台的桌面应用

Quasar 有丰富的组件可以选择,而且遵循 Material Design,巧的是我个人很喜欢 Material Design 的设计。

再加上一次编码即可生成 6 种跨平台的应用,反正我是没找到能与 Quasar 匹敌的框架。

快速开始

需要先安装 Quasar CLI

yarn global add @quasar/cli
# or
npm install -g @quasar/cli

接下来初始化项目:

yarn create quasar
# or:
npm init quasar

网页预览:

quasar dev

预览

可以看到,Quasar 的初始化项目就包含了一个抽屉菜单,满满的 Material Design 风格。

打包:

quasar build

更多信息可参考官方文档「Quick Start」。

开发

跟 Tauri 类似,只要会 Vue 就可以进行开发了,这里不赘述。

Quasar 提供了样式、布局、Vue 组件、Vue 指令、插件和工具等丰富内容,使开发更加容易,具体内容可阅读文档进行了解。

开发移动应用

开发移动应用有两种方式:

  • Capacitor
  • Cordova

这里以 Capacitor 为例开发安卓客户端,需要做好 Android Studio 相关配置,具体可参考「Preparation for Capacitor App」。

添加 Capacitor 模式:

quasar mode add capacitor

预览:

quasar dev -m capacitor -T android

此时会自动编译代码并启动 Android Studio,点击 Run app 按钮即可安装客户端并进行预览。

Android Studio

提示:Android Studio 打开后可能会提示升级 Gradle,直接忽略就好,千万不要升级。

Android 预览

打包:

quasar build -m capacitor -T android

如果打包报错,可以使用下面命令生成最终资源,然后使用 Android Studio 进行打包。

quasar build -m capacitor -T android --ide

更多关于移动客户端开发的信息可以参考「Developing Mobile Apps」。

开发 Electron 应用

添加 Electron 模式:

quasar mode add electron

预览:

quasar dev -m electron

Electron 预览

打包

quasar build -m electron

更多关于 Electron 客户端的信息可以参考「What is Electron」。

项目目录

┌── public
│   ├── icons
│   └── favicon.ico
├── src
│   ├── assets
│   ├── boot
│   ├── components
│   ├── css
│   ├── layouts
│   ├── pages
│   ├── router
│   └── App.vue
├── src-capacitor
│   ├── android
│   ├── node_modules
│   ├── www
│   ├── capacitor-flag.d.ts
│   ├── capacitor.config.json
│   ├── package.json
│   └── yarn.lock
├── src-electron
│   ├── icons
│   ├── electron-flag.d.ts
│   ├── electron-main.js
│   └── electron-preload.js
├── README.md
├── index.html
├── jsconfig.json
├── package.json
├── postcss.config.js
├── quasar.config.js
└── yarn.lock

可以看到,Quasar 的项目目录跟 Vue 基本一致,多出来的 src-capacitorsrc-electron 分别是 Capacitor 和 Electron 的相关资源。

生成图标

为了快速生成各平台下的图标,Quasar 提供了 Icon Genie CLI,使用方法如下:

icongenie generate -i 图片路径

原始图片最好是 1024x1024px 及以上尺寸的 png 图片,执行命令后即可生成各平台下的 icon。

可查看「Icon Genie CLI Command List」进行详细了解。

界面展示

展示一下我使用 Quasar 开发的应用页面。

登录

首页

抽屉菜单

新增数据

文件上传

图片预览

文本复制

关于

Quasar 踩坑

Android 相关

logo 放大

在部分设备上 App 的 logo 会放大,我的处理是删除 anydpi-v26 相关的资源文件。

删除 anydpi-v26

状态栏颜色

styles.xml 里的 AppTheme.NoActionBar 增加以下代码:

<item name="colorPrimaryDark">@color/colorPrimaryDark</item>

重复显示启动画面

在 Android 12 及更高版本上会显示两个启动画面,第一个是 Android 系统默认的,第二个是 Capacitor 生成的。

暂时未处理,更多相关信息了访问 Migrate your existing splash screen implementation to Android 12 and higher 了解。

启动画面显示黑色背景

部分手机启动画面会显示黑色背景,我的处理是将 styles.xml 里的 AppTheme.NoActionBar 改为 Theme.AppCompat.Light.DarkActionBar

启动页面 logo 拉伸变形

部分手机启动画面的 logo 会拉伸变形,我的处理是修改 capacitor-androidcom.getcapacitor 下的 Splash 类。

String scaleTypeName = config.getString(CONFIG_KEY_PREFIX + "androidScaleType", "FIT_XY"); 中的 FIT_XY 修改为 CENTER_CROP

复制文本报错

复制文本会提示 NotAllowError: Write permission denied,复制未生效。

首先修改 com.getcapacitor 下的 BridgeActivity 类,在 load 方法里增加下面的代码:

webView.getSettings().setJavaScriptEnabled(true);
webView.addJavascriptInterface(new WebAppInterface(), "NativeAndroid");

然后增加 WebAppInterface

public class WebAppInterface {
    @JavascriptInterface
    public void copyToClipboard(String text) {
      ClipboardManager clipboard = (ClipboardManager) getSystemService(Context.CLIPBOARD_SERVICE);
      ClipData clip = ClipData.newPlainText("datasync", text);
      clipboard.setPrimaryClip(clip);
    }
}

最后在 Vue 代码里增加平台判断,当处于 android 平台时调用上面定义的 copyToClipboard 方法,否则则调用 Quasar 的 copyToClipboard 方法:

copy(content) {
  if (this.$q.platform.is.android) {
    NativeAndroid.copyToClipboard(content);
    this.$q.notify({
        color: "primary",
        textColor: "white",
        icon: "check",
        message: "复制成功",
        timeout: 500,
      });
  }else{
    copyToClipboard(content)
    .then(() => {
      this.$q.notify({
        color: "primary",
        textColor: "white",
        icon: "check",
        message: "复制成功",
        timeout: 500,
      });
    })
    .catch((error) => {
      this.$q.notify({
        color: "negative",
        textColor: "white",
        icon: "clear",
        message: error + "复制失败",
        timeout: 500,
      });
    });
  }
}

返回按键无响应

Quasar 的配置文件 quasar.config.js 里可以配置 backButtonExit,用于处理应用的返回退出,但是我尝试配置后,在登录页面点击返回按键无响应。我的处理是在登录页面的 beforeRouteLeave 增加判断:

beforeRouteLeave(to, from, next) {
  if (
    this.$q.platform.is.android &&
    this.$q.platform.is.capacitor &&
    to.fullPath == "/"
  ) {
    if (currentUser) { // 登录状态
      next(true);
    } else {
      NativeAndroid.exitApp();
    }
  } else {
    next(true);
  }
}

其中 exitApp 方法在上面提到的 WebAppInterface 里添加即可:

public class WebAppInterface {
    @JavascriptInterface
    public void exitApp() {
     getBridge().getActivity().finish();
    }
}

WebView 版本

Capacitor 对 WebView 版本的要求是 60 及以上,如果 Android 设备的 WebView 低于此版本打开软件会显示白屏,解决办法是升级 WebView。

可访问 Android System WebView APK,查找需要的版本进行下载安装。

实测在三星 Note4(Android 6.0)上安装 60 版本的 WebView 依然显示白屏,索性升级到 70 版本显示就正常了,如有同样问题可以参考升级到更高的版本。

导航栏滚动

在布局中定义了类似于 Android ActionBar 的组件,正常情况下 ActionBar 应该固定位置和高度,但是实际滑动页面的时候 ActionBar 在低版本 Android 会显示发光效果,尤其在高版本 Android 上会出现拉伸和反弹的效果,与预期不符。

之所以产生这种情况是因为所谓的 ActionBar 其实是网页的一部分,而出现的发光、拉伸和反弹效果其实是 Android 的默认滚动效果,暂时无解,除非用 Android 原生组件。

Electron 打包

如果选用了 builder 方式进行打包,那么打包的时候可能会提示 electron-builder could not build Error: Exit code: ENOENT. spawn /usr/bin/python ENOENT,这是因为较低版本的 electron-builder 依赖于 Python2 打包,但是在电脑上没有找到 Python2。

解决办法是升级 electron-builder 到 23 即可:

"electron-builder": "^23.0.0",

v-ripple

Quasar 按钮、菜单等组件默认自带 v-ripple 属性,即水波纹点击效果,但是如果点击后出现抽屉菜单或者跳转页面,则来不及显示水波纹效果,体验不流畅。

暂无解决办法。

总结

体验下来,感觉 Quasar 的优势还是很明显的:

  • 开箱即用的 UI 组件,遵循 Material Design
  • 支持 SPA、SSR、PWA、BEX、手机 App 和跨平台的桌面应用
  • 打包后的手机 App 安装包体积很小

虽然桌面客户端安装包的体积比较大,但个人感觉还是要比 Tauri 更强大,跨平台的体验更一致,也更适用于商业项目,毕竟目前市面上 Electron 应用占有相当大的比例。

如果需要同时开发手机 App、桌面应用和网站,可以考虑使用 Quasar。

本文由 掘墓人 创作,采用 CC BY-NC-ND 4.0 DEED ,转载或翻译请注明出处。
最后编辑时间为: 2023年04月30日

欢迎关注我的公众号,及时获取最新文章推送。