跨平台开发之 Quasar
  分类: 佳软推荐   评论: 1 条

跨平台开发之 Quasar

in 佳软推荐 with 1 comment

使用 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 安装的包在客户端上会报错。

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

Quasar

官方仓库: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,对我个人而言,有以下两点:

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 为例开发安卓客户端,需要做好 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 的优势还是很明显的:

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

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

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