【筆記】快應用QuickApp(hap) -- 構建一個微博應用


一、背景

  在上次和小伙伴分享了快應用(后面簡稱hap)后,有很多待定的思路沒有去嘗試。這周有時間簡單開發了一個熱門微博的應用,主要涉及到的難點:富文本、長列表、畫廊。這里將整個開發過程中遇到的問題以及解決思路和方法分享給大家,希望對想踩坑的各位有所幫助。

  代碼:https://github.com/SmileSmith/quickapp-weibo

  PS:快應用目前好像還沒有發布正式版,中間會包含一些吐槽(紅字),歡迎指導和拍磚~

二、開發問題和難點記錄

1、前期准備

  注意package.json中的toolkit和packager的版本號,表明hap工程toolkit的版本,建議執行 hap update --force更新到最新版本,支持更多特性。

"toolkit": "0.0.30",
"packager": "0.0.5"

  例如在【原創】快應用QuickApp--HelloWorld體驗中,這個版本還是0.0.26,babel還不支持stage2。目前0.0.30版本已經默認支持。

  執行 hap update --force會導致.babelrc和.eslintrc.json被刷新,請注意。

2、目錄結構

  因之前項目的習慣,不喜歡直接將頁面的文件夾放在src下面,改為統一放在src/pages下,在mainfest.json修改如下

  "router": {
    "entry": "pages/Home",
    "pages": {
      "pages/Home": { // 加上pages/ "component": "index"
      },
      ...  
  },
  "display": {
    "titleBarBackgroundColor": "#e6162d",
    "titleBarTextColor": "#eeeeee",
    "menu": true,
    "pages": {
      "pages/Home": { // 加上pages/ "titleBarText": "主頁",
        "menu": false
      },
      ...

3、內部接口封裝

  內部接口中涉及異步操作的,大部分和微信小程序一樣使用 success、fail 的回調實現。為方便后續開發,用Promise簡單封裝了內部接口,並保持接口名稱與微信小程序一致。然后在app.ux中全局導入$app中。

  這樣,在各個頁面中就不需要反復寫  import router from '@system.router';  或 var router = require(''@system.router''),直接使用this.$app.api()即可。

  詳情見src/utils/mv.js、src/utils/app.ux

 

 

4、長列表使用內部組件List

  請先參考官方List教程說明,注意下面的性能優化建議,這里着重說明幾點:

  1、List通過對不同結構的列表元素設置不同type對列表的元素設置唯一的tid,以實現DOM結構復用,提升滑動和渲染的性能表現

  2、官方說明中使用對象池概念的memList,在數據量大的情況下會導致渲染對象List丟失,這點和小程序很像。所以本項目沒有使用memList的做法

  3、目前遇到兩個問題

    (a) List中的子組件使用if和for進行判斷渲染時,會刷新不及時。表現為:修改了if中的條件,但是界面沒有刷新

    (b)在List中嵌套for循環,for循環的子組件如果是可復用的DOM標簽,會導致DOM節點被錯誤復用。表現為,下圖中a微博的圖片出現在b微博中。

    

    <block for="(picIndex, pic) in backPics"> // image標簽會因為復用,混亂地出現在不同的子元素中
      <image if="{{showIndex === picIndex}}" class="picture {{enterClass}}" src="{{pic}}" @swipe="changePic()"></image>
    </block>
  <text class="gallery"> // text中的span是行元素,不會復用,在List中嵌套這樣的組件可以正確得渲染到各個父組件上
    <block for="(picIndex, pic) in backPics">
      <span if="{{showIndex === picIndex}}" class="picture {{enterClass}}" src="{{pic}}" @swipe="changePic()"></span>
    </block>
  </text>>

 

 

4、富文本

  官方的rich-text支持快應用格式的html字符串,所以微博接口返回的原生html字符串中含有<icon></icon>等表情,不能使用。

  項目參考在小程序中的做法,先用正則過濾,並遍歷形成內容數組,然后在template中for循環出來。詳情見 src/components/richContent.ux

  目前有個問題:

  用text嵌入span和a,text中不支持image或其它形式的圖片,無法展示表情icon。

  如果采用div嵌入text、a和image,又會遇到List中元素錯亂問題。

 

5、畫廊展示大圖

  開始的做法,開發一個gallery組件,放在全局,然后通過消息控制,然而還是遇到List渲染問題。

  目前采用頁面的做法,通過路由傳參數。一是可以做到全屏,二是避開List優化的問題。詳情見 src/pages/Gallery/index.ux

  利用stack覆蓋的特性,將小圖和加載動畫放在下面,然后等待大圖加載,大圖加載完畢后會覆蓋小圖和加載動畫。

  <stack class="gallery">
    <block for="(picIndex, pic) in backPics"> // 在列表中已經加載好的小圖,保證用戶能第一時間看到內容,雖然是模糊的
      <image if="{{showIndex === picIndex}}" class="picture {{enterClass}}" src="{{pic}}" @swipe="changePic()"></image>
    </block>
    <progress class="load-progress" type="circular"></progress> // 加載動畫
    <block for="(picIndex, pic) in showPics"> // 大圖,等待加載完畢后覆蓋小圖和動畫
      <image if="{{showIndex === picIndex}}" class="picture {{enterClass}}" src="{{pic}}" @longpress="longpress" @swipe="changePic()"></image>
    </block>
    <div show="{{showIndex > 0}}" class="button left-button" @click="changePic({direction: 'right'})"><text>«</text></div>
    <div show="{{showIndex < showPics.length - 1}}"  class="button right-button" @click="changePic({direction: 'left'})"><text>»</text></div>
    <div class="button back-button" @click="closeGallery"><text>︽</text></div>
  </stack>

  目前有個問題:

  同一元素不支持同時監聽click和swiper事件,所以無法實現點擊返回列表

  大圖渲染問題,實測大圖在高寬比不超過屏幕時,顯示正常;超過時(如長圖片)會導致渲染模糊,越長越模糊:

 

5、樣式類問題

  • 沒有樣式繼承,div中寫的font-size只無效的,必須寫在對應的text或span中
  • justify-content 不支持 space-around,可以用容器包裹,容器padding實現。
  • position只有fixed,要實現relative用padding調整位置
  • border不支持border-left寫法,需要border: 0px solid #eeeeee; border-left: 1px;
 

5、Debugger

  在調試器中點擊開始調試,在代碼中打上debugger,就能調試了。

 

三、總結

快應用整體還處於beta階段,許多特性還有問題,希望官方盡快解決吧。整體寫法偏向小程序,以后類似mpvue的東西應該也會出現;性能優於小程序,目前生態小,最大的問題還是推廣。。。

之前想到的幾個方向,目前還有兩個在探索中,有結果再寫吧。

1)組件 √

2)路由 

3)原生接口 

4)全局狀態管理:考慮繼承mobx或類似的flux組件

5)類型檢測: 考慮用ts

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM