使用 Quasar 可以真正做到一次编码,全平台客户端覆盖。
上一篇文章「跨平台开发之 Tauri」,主要记录了桌面端应用的跨平台开发,这次要记录的框架 Quasar 比 Tauri 更强大,不仅能开发桌面端应用,还支持手机 App 和网页端等。
需求
我的需求是这样的,做一个跨平台的软件,至少要有手机端、电脑端和网页端,类似于一个网盘,可以上传文件或文本。
之所以要做这样一个软件,是因为以下两种使用场景:
- 要给旧手机分享文件或配置文本
- 临时使用一台电脑,需要安装软件或者登录网站
为什么不使用微信或者网盘呢?
- 微信不够轻量级,在旧手机上可能带不动或者很慢
- 网盘下载文件一般都需要安装客户端,临时下载文件不想装客户端
那为什么要做手机端、电脑端和网页端呢?
- 在手机上使用客户端要比网页体验更好
- 电脑端是给主力电脑使用,用于文件上传,如果无法实现客户端网页端也可以
- 网页端是给临时要下载文件或者传输文本的电脑使用,用完即走
又是跨平台开发,那么选什么框架呢?
框架选择
本来想考虑一下 Tauri 的,但是支持手机客户端的版本 2.0 还是 Alpha 版,只好寻找其他框架。
uni-app
首先想到的是 uni-app,uni-app 号称能够「一套代码编到14个平台」,除了 Android、iOS 和 Web,还有一众的小程序。
在尝试编码的过程中,我发现了 uni-app 的两个问题。一是生成的 Android 安装包比较大,初始体积就在十几兆。最致命的是第二个问题,通过 npm 安装的包在客户端上会报错。
尝试解决无果后,只好再次寻找其他框架。
Quasar
官方仓库:https://github.com/quasarframework/quasar
在搜索其他框架的时候,我多次看到了「Quasar」。回想起来我自己的收藏里好像也有这个,但当时看到 Quasar 网站的时候感觉有点不够亮眼,就直接跳过了。
入门视频
在没有其他可选框架的情况下,我抱着尝试的心态,打开了 「Why Quasar」 的介绍视频,结果发现进入了新大陆。
视频展示了如何在半小时内制作一个 TODO 应用,并且可以在 Android、iOS、Mac、Windows 和网页上使用。看视频的第一眼我就被 Quasar 开发出的软件界面给吸引了,居然可以做出如此优美的界面,差点就被 Quasar 不够吸引人的网站给迷惑了。
推荐初学者先看一下入门视频「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# ornpm 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 为例开发安卓客户端,需要做好 Android Studio 相关配置,具体可参考「Preparation for Capacitor App」。
添加 Capacitor 模式:
quasar mode add capacitor
预览:
quasar dev -m capacitor -T android
此时会自动编译代码并启动 Android Studio,点击 Run app
按钮即可安装客户端并进行预览。
提示:Android Studio 打开后可能会提示升级 Gradle,直接忽略就好,千万不要升级。
打包:
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
打包
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-capacitor
和 src-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
相关的资源文件。
状态栏颜色
在 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-android
里 com.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。