程序人生 A log of my life

Quasar框架

简介

Quasar是我用的最多的一个桌面、移动自适应UI框架,演示页面看起来很不错,文档写的很好。下面是Getting Started的精简版本:

#列出可以用的模板,不是必须的步骤
quasar list
#初始化一个项目,需要回答一些问题
quasar init helloworld
cd helloworld
yarn
#运行dev server
quasar dev

上面用的default模板基本上基于VUE的webpack模板,所以可以参考vue的资料,quasar dev具备hot reload特性。其他一些命令举例:

  • quasar build 构建product版本
  • quasar serve 运行一个静态http服务,其实和quasar无关,但是用起来比较方便,如果之前有build,这个命令自动serve dist这个目录
  • quasar new template name 基于模板生成一个名称为name的组件

库大小比较

和几个类似的库比较一下,均是gzip后结果

  js css
vue 73k 0k
Quasar 0.14 95k 17k
Vuetify 1.1.8 152k 29k
Buefy 0.6.6 124k 29k

theme

quasr内置两个样式mat和ios,quasar dev为了支持调试android应用,自动按照theme去proxy cordova提供的platform_www内容(也就是通过theme识别android还是ios),导致没办法在android dev时使用ios theme,会提示找不到cordova.js,但不影响release版本,变通方法是debug时强制通过命令行参数使用mat theme,构建的theme则通过config文件指定。

layout

quasar layout(QLayout)很有特色,支持了一个自定义的九宫格,可以对整体的布局通过九个字符做自定义,参考下图:

四个角落的h/f可以控制header、footer是否延伸到左右,上下的大写的H/F控制header、footer是否绝对定位,左右的L/R则控制左右的侧栏(left和right)是否独立滚动,所有的组合起来,还是蛮灵活的,这里有测试页面

QLayout下面的slot除了上面header、footer、left、right还可以有navigation,这样组合起来的话,大部分常规的ui布局都可以做到了,下面是一个例子:

<q-layout ref="layout" view="lHh Lpr fff">
    <q-toolbar slot="header" class="glossy">
      <q-btn flat @click="$refs.layout.toggleLeft()">
        <q-icon name="menu" />
      </q-btn>
      <q-toolbar-title>
        <div slot="subtitle"></div>
      </q-toolbar-title>
    </q-toolbar>

    <div slot="left">
      <q-list >
        <q-list-header>xxx</q-list-header>
        <!-- replace告诉vueroute替换当前路由,而不是push,这样回退按钮不会退回上级 -->
        <q-side-link item to="/practice" replace>
          <q-item-side icon="music note" />
          <q-item-main label="yyy" sublabel="zzz" />
        </q-side-link>
      </q-list>
    </div>
    <router-view />
  </q-layout>

上面的ref是vue的一个属性,用于在下面的q-btn中可以访问,参考这里

flex布局

quasar对flex布局做了简单封装,其中最容易疑惑的三个class是对flex子元素的封装:

  • col-auto 相当于 flex 0 0 auto, 也就是固定元素
  • col 相当于 flex 1 ,也就是 flex 1 0 0, 就是自动扩展
  • col-N 相当于 flex 0 0 N/12%,就是传统的12格布局

cordova

quasar对移动端也支持的,对移动端的支持通过wrap命令完成,比如增加cordova支持,可以

quasar wrap cordova

这样会在目录下建一个cordova子目录,cordova下是一个标准cordova工程,但通过符号链接把www目录链接到quasar的dist目录,但是wrap的时候在我的机器上符号连接建不起来,报一个Permission错误,这里有调整权限的解决方法,不过我还是不能成功,只能手工用管理员模式启动命令行,删除cordova目录,再执行一遍quasar wrap cordova就好了。

之所以把dist目录而不是src目录链接过去,是因为src目录未经过webpack是不能直接在webview中运行的, 使用dist带来了手机调试的困难,每次修改代码,quasar build,然后再重新cordova run都是比较漫长的过程。官方的一个推荐方法是修改cordova的配置文件,把其中<content src="index.html" />替换为quasar dev服务的地址,比如<content src="http://192.168.1.1:8080" />,这样构建出来的应用实际上是一个指向开发机的空壳,同时也可以做hot reload了, cordova插件也可以访问,一举多得。

注: 这是quasar 0.14对cordova的支持方式,从0.15开始,quasar对cordova的支持做了很大改变,不再需要符号连接,参考下文。

quasar play

cordova建好之后,可以通过标准的cordova工具链就进行移动端编译、运行,也可以通过quasar play这个工具去做,quasar play非常类似React Native使用的Expo,好处自然是支持部署方便,且支持hot reload,但目前不能支持cordova plugin功能,官方文档是这样写的:

While playing with your App in Quasar Play, Cordova functionality will currently not be available. This is due to Cordova Javascript code causing a crash in its Java container.

所以quasar play其实没什么用,不如直接使用上面的替换content src的方法,更方便快捷。

手势

quasar支持三种手势Pan、Swipe、Hold。

  • Hold 在按下手指没有移动,并持续一段时间后触发,没有拿起手指之前只触发一次。并且在时间不足的时候,如果移动手指,即使后面持续按住,也不触发事件。
  • Swipe 在按下并移动,然后松开的时候触发一次,方向由总体的方向决定,只有上下左右四个方向,即使斜向移动,也只触发一个最接近的方向。
  • Pan 在按下并移动时连续触发。

上面三种手势可以同时挂接在同一个DOM元素上,Quasar可以正确的按照上面的逻辑处理。

grid

UI框架对grid(data table)的支持是至关重要的,遗憾的是quasar 0.14虽然自带了一个dataTable,但功能上不是很完善,基本复杂一些的表格很难完成,期待后续版本完善吧。0.15要好很多,可以支持了服务器端分页等重要特性。

轻量化

缺省的quasar mat模板带了google roboto字体(ios模板不带),这个会被webpack build到dist,占用200k空间,如果不想用这个字体,直接在main.js里注释掉

if (__THEME === 'mat') {
  require('quasar-extras/roboto-font')
}

就可以了。类似的,如果不需要Material Icon(50k),可以注释

import 'quasar-extras/material-icons

但是由于一些控件使用了Material Icon,直接注释会导致这些控件显示不正常,所以要小心测试。

form

quasar在q-btn组件上使用了div,因此想使用enter提交form的话,需要在相应的input上做文章,简单的说就是增加下面这个属性:

@keyup.enter="submit"

兼容性

quasar借助cordova实现了对android和iOS的支持,但是有一个坑,Material Icon在android 4的webview下不支持(大量图标显示不正常或错位),所以如果希望兼容Android 4,必须使用替代的图标,个人觉得ionicons非常不错,可以作为不怎么好用的Material Icon的替代和补充。

另一个需要考虑的兼容性是浏览器可能不支持Promise等特性(如IE,或低版本Android),通常可以导入Polyfill来解决这个问题。

quasar也有一些兼容性需要考虑,比如quasar 0.15需要node 8以上版本,所以如果不能使用node8,就需要使用quasar 0.14的版本了。

quasar 0.15除了node版本要求更高,对真机调试安卓的手机也有更高要求,需要android 6以上版本,否则在调试模式插件不能工作,这点很奇怪,目前还没有很好的规避方法。

自定义组件

vue不支持类似对组件进行继承,只能通过”合并”(composite)的方式来实现自己的组件。这种方式在改写quasar已有的组件就比较麻烦,需要将已有组件的”依赖”全部找到并合并进来,尤其是quasar使用了很多mixin的写法,导致依赖比较多,暂时没有发现更好的方法。

自定义脚手架模板

quasar高版本的cli的init不支持自定义模板了,但是还好,可以通过vue的init来自定义自己的模板,这样对于团队使用自己的统一模板还是很有帮助的,但如果以这种方式做模板,模板文件并不是简单复制到目标项目,而是经过metalsmith处理,所以模板里的vue文件需要再经过一次render,巧合的是metalsmith的render也是用这个格式,所以对于vue文件本身的模板变量,需要加反斜杠转义,这点颇有不便。

vue init user/repo

这个模板的repo需要是github上的,如果是非github的,要加前缀,比如:

vue init bitbucket:user/repo projectname 

如果不是团队使用,也可以用本地目录代替远端仓库,init后面跟相对地址就可以了,比如..\template\dir

自定义整个quasar

  • fork quasar
  • 在package.json里把dependency里的quasar-framework修改为类似i38/quasar#v0.14这样的github库
  • yarn
  • cd node_modules\quasar-framework && npm install && npm run build

这样就可以了,如果还想直接调试quasar源码,可以在webpack alias里增加一个quasar_src: path.resolve(__dirname, '../node_modules/quasar-framework/src/index.esm.js'),然后把main.js里import quasar的地方改为import quasar_src

缺点

  • 对浏览器的要求IE11+,并且对IE11需要特别的修正
  • 移动端缺乏一些流行的控件,比如可滑动的Tab页。

版本升级

quasar 0.14到0.15有巨大的升级,尤其是工程方面变化巨大,几乎完全不兼容,如果有项目仍在使用0.14,一旦全局的quasar-cli升级后,老的项目下quasar命令都不能正常运行了,在老项目下推荐使用npm run的方式去启动编译和构建,还能保持兼容。新项目还是应该使用新版本,新版本几个优点:

  • 不需要在页面里注册控件了,在quasar.conf.js里统一注册了
  • webpack4即时编译的效率明显提高
  • datatable控件改进明显
  • cordova的支持不再需要符号链接www目录

新版本发现的一些问题:

  • quasar 0.15在处理cordova下的返回键时,有特殊处理,只有在根route才能退出应用,不知道为什么有这个限制
  • 在android5下,quasar 0.15的debug版本挂接不了backbutton事件了,大部分插件也不工作了,但通过quasar build的release版本是好的,或者更换到更新的android版本也可以。
  • quasar 0.15一些组件的click事件需要改为click.native
  • 0.15下android的back键会先关闭popover,所以如果从popover跳转其他页面,需要先在btn上加上v-close-overlay(关闭popover),否则跳转过去后,要两次back才能返回。