快應用,快入門

已禁用發表於2018-04-03

作者:餓了麼 顧誠

開篇也不扯那些沒用的,讓我們高效的開始教程。

在一切教程開始前

無論學習什麼語言、框架、庫,首先你要做的,就是登陸它的官網,認真閱讀它的入門手冊、文件等,這比任何《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 專案程式碼,右邊是快應用程式碼,我們來逐一分析:

new 元件 diff

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 專案程式碼,右邊是快應用程式碼

store 模組 diff 圖

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.

相關文章