快应用,快入门

作者:饿了么 顾诚

开篇也不扯那些没用的,让我们高效的开始教程。

在一切教程开始前

无论学习什么语言、框架、库,首先你要做的,就是登陆它的官网,认真阅读它的入门手册、文档等,这比任何《xx 分钟从入门到精通》、《xx 深入浅出》都要靠谱得多,再加上现在编程体系的愈加完善,开发者越来越注重基础设施的搭建,官网绝对是学习一样东西的首先选择。 所以,快应用现在的 官网是:https://www.quickapp.cn 文档是:https://doc.quickapp.cn 请认真阅读文档。

在快应用的教程开始之前

快应用宣传的一大优势,就是对于 Web 前端开发者的低学习成本、快速上手。那么它的这个优势,其实是建立在你熟悉(有一定程度了解)类 Vuejs 的框架的前提上的。 它基本上是建立在 Vue 的体系上的,经过一定程度的改造、精简,形成了快应用的开发体系。 本篇教程,也默认你对 Vue 已经有一定程度的了解,假如你还没有完成这个前提,那么先去了解一下 Vue 也不错。 所以,让我假设阅读本文的你,是一名拥有 Vue 经验的 Web 前端开发者,对新出的快应用有一定兴趣,想要了解一下它,那么,希望文章对你有所帮助。

教程前置准备

上文也说了,快应用的开发,对比的就是 Vue 的体系,所以,我选择通过对比同样实现目标的 APP 的 Vue 版本和快应用版本,来说明你要进行快应用开发需要准备和了解哪些东西。 首先,我选择了人民群众喜闻乐见的 HackerNews 作为实现目标,它提供了完善的 API,方便我们构建真实 APP,并且 Vue 的官方也有一个 Demo 版本的 HackerNews 源码,省去了我们不少工作。 所以我们直接选择 https://github.com/vuejs/vue-hackernews 当前 master 分支作为 Vue 版本的代码,你们也可以自行 clone 查看。

快应用项目初始化

请根据快应用官方文档的快速入门一节,准备好开发环境,在这里只有一点提醒:假如你的手机还没有直接支持快应用的运行环境(提示没有运行环境),请安装「快应用平台预览版」,通过它进行调试。

开始

首先确认一下我们的工程结构

.
├── quickapp
│   ├── README.md
│   ├── build
│   ├── dist
│   ├── node_modules
│   ├── package-lock.json
│   ├── package.json
│   ├── sign
│   └── src
└── vue
    ├── LICENSE
    ├── README.md
    ├── index.html
    ├── node_modules
    ├── package.json
    ├── src
    ├── static
    └── webpack.config.js
复制代码

就是这样,快应用是通过 hap 工具直接初始化的工程,作为开发者,直接写代码就完事了,我想你目前应该也不关心快应用的实现原理和内部细节。

1. 第一步:入口

Vue 项目的入口自然是 index.html 和 main.js,它的核心代码结构是这样的:

src
├── components
├── filters
├── main.js
├── store
└── variables.styl
复制代码

好,看一下 main.js

import Vue from 'vue'
import Router from 'vue-router'
import { domain, fromNow } from './filters'
import App from './components/App.vue'
import NewsView from './components/NewsView.vue'
import ItemView from './components/ItemView.vue'
import UserView from './components/UserView.vue'

// install router
Vue.use(Router)

// register filters globally
Vue.filter('fromNow', fromNow)
Vue.filter('domain', domain)

// routing
var router = new Router()

router.map({
  '/news/:page': {
    component: NewsView
  },
  '/user/:id': {
    component: UserView
  },
  '/item/:id': {
    component: ItemView
  }
})

router.beforeEach(function () {
  window.scrollTo(0, 0)
})

router.redirect({
  '*': '/news/1'
})

router.start(App, '#app')
复制代码

很简单,做了几件事情:

  1. 引入框架(Vue,VueRouter)
  2. 引入组件
  3. 定义 filters、路由
  4. 启动应用

OK,那么我们去快应用里面看一下,快应用里,一个 APP 的 入口,是 src/manifest.json,一个 APP 的重要信息就定义在这里面,我们看一下

{
  "package": "me.ele.hacknews",
  "name": "quickapp-hackernews",
  "versionName": "1.0.0",
  "versionCode": "1",
  "minPlatformVersion": "101",
  "icon": "/Common/logo.png",
  "features": [
    { "name": "system.prompt" },
    { "name": "system.router" },
    { "name": "system.shortcut" },
    { "name": "system.fetch" }
  ],
  "permissions": [
    { "origin": "*" }
  ],
  "config": {
    "logLevel": "debug"
  },
  "router": {
    "entry": "News",
    "pages": {
      "News": {
        "component": "index"
      },
      "User": {
        "component": "index"
      },
      "Item": {
        "component": "index"
      }
    }
  },
  "display": {
    "titleBarBackgroundColor": "#ff6600",
    "titleBarTextColor": "#ffffff",
    "menu": true,
    "pages": {
      "News": {
        "titleBarText": "Hacker News | QuickApp Clone"
      }
    }
  }
}
复制代码

当然,这和你刚初始化完成时候的配置肯定不一样了,不过我只是改成了 HackerNews 的配置,结构并没有改变,来看一下:

  1. 定义好包名(package)、应用名(name)、logo(logo)
  2. 定义需要用的系统接口(features),所以上文让你认真看文档,调用系统接口都是需要提前声明(你也不想用户说你滥用权限对吧),这里我们需要router(路由)、fetch(网络请求)
  3. config.logLevel 先改成 debug 好了,输出所有 log
  4. router 中定义好所有路由,entry 就是首页,pages 和 component 对应好
  5. display 你可以先不管(不过也没什么难度就是了)

那么对比 Vue 的启动配置来说,因为快应用是运行在系统集成环境中的,所以 Vue 项目要求的引入框架、库(路由)就都不需要了,多出了系统接口的提前声明,按需声明就可以了,这项目只需要最基本的路由、网络请求权限就可以了。

路由这块,请参考官方文档,稍微需要注意的就是 page 默认使用它的名称文件夹作为它的组件所在位置。基本上也和 Vue 版本的路由对应的配置就可以了,需要注意的是路由参数不需要在这里配置,而是在对应的组件内配置(作为组件外部传入属性)。

到这里,你就已经完成了快应用项目的基础配置,当然,现在是运行不起来的,你配置的页面还没有实现对应的组件,下面我们就把 Vue 的页面组件改造成快应用的组件。

2. 改造 Vue-> QuickApp

看一下快应用版本的源代码目录结构

src
├── Common
├── Item
├── News
├── User
├── app.ux
├── filters
├── manifest.json
├── store
└── util.js
复制代码

一个页面对应一个目录,app.ux 是入口组件(现在不用管它),我们开始改造过程。

第一个页面就是首页(News),上改造前后对比图,diff 图左边是 Vue 项目代码,右边是快应用代码,我们来逐一分析:

template 部分
  1. 自定义组件引入,用特殊的 import 标签引入,直接可以在 template 中使用
  2. 用 list 组件提高列表性能,就先把它当成 div 好了(想要进一步了解,请阅读官方文档,list 优化一节)
  3. 快应用不支持 :before, :after 伪类,因此 loading 文字只能用一个单独的元素并根据条件来展示了。
  4. 你也发现在快应用中:
    • v-show -> show
    • v-for -> for
    • v-if -> if
    • :property -> property="{{ }}"
    • track-by -> tid
    • $index -> $idx 基本上就是去掉了 Vue 特色,变成了通用单词。 另外,大部分表达式使用时(除 for、tid 等),要写在 {{ expression }} 中,需要注意一下。
  5. 文本写在 text 组件内!(请认真阅读文档),这和 Web 开发有很大区别,HTML 的体系中,基本是个标签就能加文本,但是快应用中不行,需要绑定在 text 组件内。文本写在 text 组件内!文本写在 text 组件内!
  6. 没有 filter,这个在某些情况下确实有些不方便,只能改造成函数了 $index | formatItemIndex -> formatItemIndex($idx)

完成以上步骤,你的 template 部分就基本改造完成了,对着手册一一改造就可以了。

script 部分

这部分改动很少,快应用支持 ES2015 的绝大部分语法、特性,这里有一个不好的地方,官方没有详细说明支持程度,可能会遇到支持性问题。

  1. 引入路由服务,因为需要手动跳转(快应用也支持 href 跳转,这里只是为了演示),使用系统服务,就按照正常的引入项目模块的逻辑来进行就可以了。
  2. 不在 script 引入自定义组件。
  3. 生命周期,改个名字,常用的就是 onInit、onReady、onDestroy,顾名思义,不懂看文档。
  4. 方法,快应用的方法不需要定义在 methods 里面,因为它的组件里,没那么多其余属性,直接在组件对象第一层下定义方法就可以了,script 和 template 通用。因此我们把所有方法都从 methods 里面搬了出来。
  5. filters,上文说了,快应用没有 filter,就改造成普通方法好了(坏处是不能定义全局 filter,每个组件都需要反复引入 filter 方法,当然可以在 App 层面定义方法,不过不好管理)。
  6. 补上一个页面跳转的方法,可以看一下使用方式,就是普通的函数调用,uri + params

完成了以上步骤,你就基本完成了script 部分的改造,这里有一个问题,Vuex 你不禁想问,Vuex 怎么办,上面我写的那个 store,是 vuex 吗?不是。 很遗憾,假如你依赖于 Vuex,你可能会遇到麻烦,我还没有很好的办法替代 Vuex,快应用支持全局 data,支持 watch,但是并不足以替代 Vuex,上面的 store,并不是 Vuex,只是一个处理数据的服务,下文会说到。

style

style 部分看上去是最简单,但其实是最麻烦的部分:

  1. style 仅支持部分 CSS 属性
  2. 快应用使用 flex 进行布局
  3. 快应用有默认的屏幕适配(750px),你写的所有 px 单位,都会以 750px 为标准进行缩放适配,有优势,也有缺点。
  4. 快应用有一些特有的属性
  5. 快应用的选择器支持比较有限

上面这些特点,需要你认真阅读快应用文档的 style部分,以及各个组件的样式部分,来了解情况,请一定要认真阅读,你很容易用上了不支持的 CSS 特性。

我们这个 DEMO 项目的 style 比较简单,Vue 项目用了 stylus,快应用显然不支持,为了方便转成了 CSS,不过快应用支持 Less CSS,也是不错的选择。

  1. 根据 flex 布局做一些调整
  2. 把伪类改成了独立元素
  3. 移除了不支持的属性
  4. 移除不支持的伪类(hover 之类的)
  5. 适配一些不支持的缩写语法

这可能是一个体验很糟糕的过程,写着名义上是 CSS 却有那么多不同的 style 代码,不过无论如何,我们总算是完成了 style 部分的改造。

改造小结

很明显,通过以上对比,你会发现,快应用的代码体系,真的很像 Vue,但是又有那么一些糟糕的区别。 还是那句话,如果你想要进行快应用的开发,请认真阅读文档,磨刀不误砍柴工。

组件之外

显然我们的项目里,一般不会只有组件这一种东西,还有一些 JavaScript 模块,比如上文的 store,这时候正文开始了 :)。

diff 图左边是 Vue 项目代码,右边是快应用代码

what? firebase 库? 讲道理,这是一个 JavaScript 库,应该可以在快应用环境中直接使用,但是实际上,不行。

firebase 库依赖于很多浏览器(window)API,比如 XHR 请求,这时候,它就无法在快应用的体系中正常运行了。 这时候你陷入了一个两难的抉择,对 firebase 的库进行魔改,或者自己造一个 firebase 库。 这时候你可能就想放弃了,事实就是这么残酷,你会想,我做了这个事情我怎么不去加入 firebase?

但是教程总是要继续,好在我们这个项目真的很简单,简单到我不需要 firebase 的库,也可以轻松兼容原代码,完成改造。

  1. 引入 fetch API(和浏览器中 Fetch api 有一定区别)
  2. 声明 hackernews 的 firebase API host 地址
  3. 把原先的 firebase 方法 api.child 改造成直接的 fetch 调用

看上去好像也没什么问题,因为我们这里的 firebase 调用足够简单,仅仅是请求数据而已。

  1. 像是 fetch 这样的快应用系统接口,都是用 callback 回调的形式实现的
  2. 快应用支持 Promise,因此我们可以轻松实现 Promise 兼容,避免了业务层的改动
  3. 快应用也支持直接引入 Node 模块

万幸,我们完成了 store 部分的改造。

教程的尾声

然后其实也只剩下 Item、User 等组件了,依次完成改造。按照官方开发环境的说明

  1. npm run server
  2. 用手机安装调试工具(可能还需要平台预览版),扫描二维码
  3. 查看一下效果

预览图:

预览视频:

你要问了

Q: 为什么这么丑? A: 没时间调整样式,这是个 DEMO(侧面反映,普通 CSS 不能完美地直接迁移到快应用内)

Q: 为什么页面加载这么慢? A: 因为 firebase 的接口慢,并且接口是先请求 id 列表,然后逐一请求 item,最后合并返回,必然很慢,因为我们不能使用 firebase 库。。。

Q: 你吹嘘的那些快、轻量、原生完全没体现出来! A: 确实,这个 DEMO 是在太简单了,如果你有兴趣,可以尝试自己动手写一个快应用 APP,一定可以直观地感受到它和普通网页应用的区别

Q: 我看完你的教程,觉得什么都没讲?!还是不会写! A: 在教程的一开始,我已经说过了,学习一样东西,最好的方法当然是它的官网啦,其实现在快应用的快网已经非常完善了,从入门教程到手册到性能提升建议到深入实践,看完你一定有所收获。

Talk is cheap, show me the code.

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值