快應用入門,看這篇就夠了

迅雷前端發表於2018-04-03

什麼是快應用

簡單地說快應用是國內的十大主流手機廠商比如小米、華為、ov 等聯合推出的一種新型應用。無需安裝,秒開,體驗媲美原生。還提供了像原生應用一樣的入口:應用商店,搜尋頁等。

開發前準備

接下來會教大家如何搭建、啟動、預覽和除錯快應用專案。和官方文件類似,這裡我增加了一些我在這過程中遇到的坑及解決方法。

建立專案

安裝 NodeJS

官方說需安裝 6.0 以上版本的 NodeJS,推薦 v6.11.3,但我本機 NodeJS 是 v9.3.0,暫時沒發現異常就沒切到 6.0。

安裝 hap-toolkit

hap-toolkit 是快應用的開發者工具,幫助開發者通過命令列工具輔助開發工作的完成,主要包括建立模板工程,升級工程,編譯,除錯等功能。類似 vue-cli。

npm install -g hap-toolkit
複製程式碼

安裝之後檢視下版本號看是否安裝成功。

hap -V
複製程式碼

建立專案

執行如下命令會在當前目錄下建立 <ProjectName> 目錄作為專案的根目錄。

hap init <ProjectName>
複製程式碼

這個專案已經包含了專案配置與示例頁面的初始程式碼,專案根目錄主要結構如下。

├── sign                      rpk 包簽名模組
│   └── debug                 除錯環境
│       ├── certificate.pem   證照檔案
│       └── private.pem       私鑰檔案
├── src
│   ├── Common                公用的資源和元件檔案
│   │   └── logo.png          應用圖示
│   ├── Demo                  頁面目錄
│   |   └── index.ux          頁面檔案,可自定義頁面名稱
│   ├── app.ux                APP 檔案,可引入公共指令碼,暴露公共資料和方法等
│   └── manifest.json         專案配置檔案,配置應用圖示、頁面路由等
└── package.json              定義專案需要的各種模組及配置資訊
複製程式碼

安裝依賴

npm install
複製程式碼

啟動專案

編譯

npm run build
複製程式碼

編譯生成的 dist 目錄裡才是最終產物:rpk 檔案。

這一步可能會遇到報錯(我就遇到了)。

Cannot find module `.../node_modules/hap-tools/webpack.config.js`
複製程式碼

主要是因為建立專案後就有一個 node_module 資料夾了,裡面有一個 hap-tools 包。如果 npm install 安裝依賴,高版本的 npm 可能會把 node_module 原有的包清空再安裝依賴,這時只要再手動安裝下 hap-tools 就行了

npm install hap-tools
複製程式碼

如果要監聽原始碼變化自動編譯,可以執行 watch 命令。

npm run watch
複製程式碼

到這一步一個 hello world 的快應用就打包好了,下面需要在手機上把它跑起來。

預覽

首先需要安裝手機偵錯程式

快應用入門,看這篇就夠了

只安裝這個快應用偵錯程式會發現上面的按鈕都是灰色不可點選的,這時還需要安裝平臺預覽版偵錯程式,總之快應用文件上的手機偵錯程式都要安裝才能除錯。

安裝好偵錯程式後就把快應用安裝包安裝到手機上就可以了。

掃碼安裝

需要啟動一個本地 HTTP 伺服器。

npm run server
複製程式碼
快應用入門,看這篇就夠了

如果命令列中的二維碼掃了沒反應,可以把那個地址在瀏覽器中開啟在掃碼試試(我就是這樣),因為命令列中的二維碼可能繪製的有問題。

本地安裝

rpk 檔案傳到手機上安裝即可。

線上更新

快應用偵錯程式右上角可以設定伺服器地址,執行以下命令每次改了程式碼就可以點選線上更新就可以更新了,不用每次都掃碼或本地安裝。

npm run server
npm run watch
複製程式碼

除錯

可以手機上預覽,也可以使用 chrome devtools 除錯介面,還可以檢視除錯日誌。手機上預覽上面說了,其他除錯按官方步驟來就好了。

可能的坑:在用chrome devtools除錯的時候可能打不開除錯介面,或者除錯介面空白。這時需檢查:

  • 在手機偵錯程式上點選了開始除錯(點了就會自動在 pc chrome 上開啟 devtools)
  • 確保手機和電腦在同一個網段
  • 檢查代理,設定了代理的把代理關了試試(我就是因為設定了代理 devtools 空白)
快應用入門,看這篇就夠了

5 分鐘上手教程

以一個列表頁和詳情頁為例說明快應用的程式碼,資料來源迅雷影評

Manifest.json

manifest.json 中配置路由後就可以寫程式碼了,生成的模板有例子。注意不能配置動態路由。

注意用到的系統介面要先在 manifest.jsonfeature 中宣告。看 manifest 的文件瞭解具體的配置項。

{
  "package": "com.xunlei.movie",
  "name": "迅雷影評",
  "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" },
    { "name": "system.webview" } 
  ],
  "permissions": [
    { "origin": "*" }
  ],
  "config": {
    "logLevel": "debug",
    "designWidth": 640
  },
  "router": {
    "entry": "List",
    "pages": {
      "List": {
        "component": "index"
      },
      "Detail": {
        "component": "index"
      },
      "About": {
        "component": "index"
      }
    }
  }
}
複製程式碼

列表

列表使用了快應用的list元件,這個元件是Native元件,對長列表滾動效能更好,list元件還有一個onscrollbottom事件,方便下拉載入。

image元件和前端的img標籤類似,但是alt屬性不同,alt是用來顯示佔點陣圖的,只能是本地圖片,在圖片沒載入出來前顯示。

list-item元件中的type是必填的,要實現DOM片段的複用,要求相同type屬性的DOM結構完全相同;所以設定相同type屬性的list-item是優化列表滾動效能的關鍵。

<template>
  <list class="list-main" onscrollbottom="loadData">
    <list-item class="list-item" type="review" for="{{item in list}}">
      <image  class ="art-pic" 
        src="{{item.img}"
        alt="../Common/assets/img/default.png">
      </image>
      <text class="art-title">{{item.title}}</text>
    </list-item>
    <!-- 載入更多,type屬性自定義命名為loadMore -->
    <list-item type="loadMore" class="load-more" show="{{hasMore}}">
      <progress type="circular" class="round"></progress>
      <text>載入更多</text>
    </list-item>
  </list>
</template>
複製程式碼

快應用的網路請求是用fetch方法,是callback的形式,不方便呼叫,官方給了一個封裝成promise的例子,可以用async/await的方式呼叫。

將封裝好的fetch方法在app.ux中匯出就可以全域性使用了,由於我使用的介面都返回json,所以直接就在這一層解析了。實際開發時要注意JSON.parse的報錯處理。

// app.ux
const natives = {
    /**
     * 網路請求
     * @param options
     * @return {Promise}
     */
    async fetch (options) {
      const p1 = new Promise((resolve, reject) => {
        options.success = function (data, code) {
          data = JSON.parse(data.data)
          resolve({ data, code })
        }
        options.fail = function (data, code) {
          reject({ data, code })
        }
        nativeFetch.fetch(options)
      })
      return p1
    }
  }
  // 注入到全域性
  const hookTo = global.__proto__ || global
  hookTo.natives = natives
  
  export default {
    natives
  }
複製程式碼

路由跳轉

<template>
  <list>
     <list-item onclick="{{goDetail(item.id)}}" for="item in list"></list-item>
  </list>
</template>
<script>
import router from `@system.router`
  
export default {
  goDetail (id) {
      router.push({
        uri: `/Detail`,
        params: { id }
      })
   }
}
</script>
複製程式碼

webview

詳情頁只是載入了一個 webview, 用列表頁傳過來的 id 去請求影評詳情,影評正文是存在 cdn 上的一個地址。使用 web 元件前需在 manifest.json 中宣告使用 webview 介面。

<!-- Detail/indev.ux -->
<template>
  <!-- template裡只能有一個根節點 -->
  <div>
    <web src="{{review.body_url}}" id="web"></web>
  </div>
</template>

<script>
  import api from `../Common/api/index.js`

  export default {
    data: {
      id: ``, // 列表頁傳過來的id
      review: {}
    },
    onMenuPress() {
      this.$app.showMenu()
    },
    onInit () {
      this.getReview()
    },
    async getReview () {
      try {
        let data = await api.getReview(this.id)
        this.review = data.cinecism_info || {}
        this.$page.setTitleBar({ text: this.review.title })
      } catch (error) {
        console.log(error)
      }
    }
  }
</script>
複製程式碼

與前端開發比較

快應用與前端開發的最大的區別就是 html 和 css 部分,因為快應用是用原生的方式實現的,但沒有實現html的所有標籤,而且與 html 相同的標籤在用法上也有一些差別。

html

快應用中很多 html 都不能用,比如沒有 p,h1~h2 等,因為它只是模擬了部分 html 標籤,最終會轉化成原生元件。

而且快應用中的元件巢狀子元件是有限制的,不是所有的元件都能巢狀子元件,如果巢狀不正確編譯的時候會報錯。比如下面就是不正確的寫法:

<!--錯誤-->
<a href="">
 <image src="http://pic.com/1.jpg"></image>
</a>
複製程式碼

文字元件

只能使用 a、span、text、label 放置文字內容

圖片元件

圖片元件是 image 不是 img,用法與 img 類似,只是 alt 的含義不同,在快應用中 alt 是指圖片沒載入出來前的佔點陣圖,只能是本地地址。

<image src="http://pic.com/1.jpg" alt="1.jpg"></image>
複製程式碼

其他

表單元件、video 元件等與前端一致,還有一些快應用特有的元件,比如星級評分元件、進度條元件、list 元件等。

css

  • display 只能是 flex 或 none
  • position 只能是 fixed 或 none
  • 長度單位只有 px 和 %

與傳統 web 頁面不同,px 是相對於專案配置基準寬度的單位,已經適配了移動端螢幕,其原理類似於 rem。基準寬度可以在 mainifest.json 中配置。

javascript

基本語法都能用,ES6 也可以用,專案中已經安裝了 babel 依賴。一些瀏覽器特有的 API 可能不同。比如資料儲存用的是快應用的介面 storage。

與 Vue 比較

由於我們團隊主要是用 Vue 技術棧開發,所以比較下快應用在語法上和 Vue 的共同點和差異之處。快應用看起來和 Vue 類似,其實還是有很大的差別。

  • 都有指令的概念,只是寫法不同, 目前不能自定義指令
<!--左邊是 vue 語法 右邊是快應用語法-->
v-for => for
v-show => show
v-if => if
template => block
slot => slot
複製程式碼
  • 快應用的路由是通過配置檔案 manifest.json 配置的,在例項中的用法與 vue-router 一致
  • 都有元件概念,元件引入的方式略有不同
// vue
import child from `./childComponent`
// 快應用
<import name="child" src="./childComponent"></import>
複製程式碼
  • 事件的監聽和觸發與 Vue 類似,都是 $on $off $emit,監聽原生元件的事件寫法不同
<!--vue-->
<div v-on:click="handleClick"><div>
<div @click="handleClick"><div>
<!--快應用-->
<div onclick="{{handleClick()}}"><div>
複製程式碼
  • 元件間通訊和純 Vue 類似,可以通過 props,也可以掛載在全域性物件上
  • Vue 生態系統都不能用,比如 Vuex,目前沒有外掛機制

優缺點

優點

  • 提供了很多系統的功能,比如分享、通知、掃描二維碼、新增圖示到桌面
  • 使用者體驗好,無需下載,秒開,佔用記憶體小
  • 可以關聯原生應用

缺點

  • 每個平臺都要註冊個賬號
  • 沒有一個整合開發環境,除錯麻煩,且 devtools 很卡
  • rpk 檔案最大1M
  • 國內手機廠商推出的,自然是不支援 ios 了

總結

寫 demo 的時候還是遇到了不少坑,主要是 html 和 css 部分。像我們公司前端和重構是分開的,重構只負責寫 html + css,前端負責寫邏輯調介面等雜七雜八的事情,快應用和小程式這種形式對重構來說很麻煩,不能寫一份程式碼到處用了。

還有就是詳情頁顯示影評正文的時候遇到了一個問題。我們影評的正文是存在 cdn 上的一堆 html 標籤,無樣式,可能有一些和快應用不相容的標籤,所以用 webview 的方式載入頁面。但是不知道怎麼向 webview 中注入 css ,所以頁面是亂的。

總的來說,快應用這種形態對使用者來說還是很好的,在下載 APP 前就可以體驗到應用的一些功能。快應用的快在於它進行了很多原生的優化,也在於它小,小到使用者感覺不到,這也註定它不能做的很複雜。

程式碼地址

github.com/greenfavo/q…

參考文件

快應用開發文件

掃一掃關注迅雷前端公眾號

快應用入門,看這篇就夠了

作者:珈藍

校對:前端小透明

相關文章