weex開發問題記錄

最近再次更新了weex-toolkit,版本1.3.8,weexpack版本1.1.6。版本號有了小升級,沒發現什麼變化,文檔更是感受好久都沒變化了。記錄下本身發現的一些坑,只是處於探索研究階段,不少實際開發的功能還沒涉及,但僅這些皮毛已經有足夠的理由放棄了。html

Weex宣稱是一次開發、多端適配,這點上比ReactNative須要針對不一樣端使用不一樣組件開發的方式看起來美好了不少,不管是成本仍是效率,確定都有巨大的益處。一旦你相信了,興沖沖跑進去,才發現底下是一個多大的陷阱(若是能爬上來,確定有很大進步😏)。開發時,上層組件看起來是統一了,但下面實際上是N多的多端適配補丁,只是將ReactNative多端開發的不一樣下移了,並且這個不一樣仍是各端Native代碼。前端

Weex整體思想是好的,幫開發者封裝不一樣端的差別,只是感受這個活剛乾了表面一層,剩下就爛尾了。。。vue

頁面跳轉問題

頁面跳轉幾乎就是web開發的核心,多頁仍是單頁,對用戶是體驗感官問題,對開發者則是數據流程等基礎架構問題。關於頁面跳轉weex文檔並無說起,嚴格說也是說起了,前提是讀者有native開發經驗。java

單頁內跳轉

單頁基於vue-router實現跳轉,這種方式仍是傳統的web開發,能減小不少額外的問題。若是不在意依賴包的版本比較老舊,那麼基於weex-hacknews這個demo修改最簡單,相對問題也少。android

單頁最大的問題,在於你的app就真的成了一個瀏覽器容器,每次打開都是一個全新的瀏覽器。git

若是想基於weex-toolkit建立的項目作單頁開發,須要本身調整不少東西,這個腳手架自己是爲了多頁而存在的。一些不成體系的趟坑經驗見weex vue router開發嘗試github

多頁跳轉

這種方式不止是weex-toolkit腳手架應用,也是weex-ui所推薦的,但內層的機制卻須要開發者熟悉native的跳轉方式,關鍵這也是開發時必須熟知的。web

針對三端(web端是爲了方便開發),跳轉方式和路徑都是不一樣的:vue-router

  • Web端,比較簡單,使用document.location,跳轉路徑使用 /about.html 形式。
  • Android端,跳轉要基於Activity(Android開發的基礎概念,後續相關的再也不備註),有兩種方式,一是使用navigator模塊,它使用action+category方式跳轉Activity,因該模塊中寫死了category,不改變SDK的基礎上,爲了防止多個weex應用在被一樣的category呼起時衝突,需使用第二種方式,即便用 event 模塊,它會顯式調用WXPageActivity(腳手架中的java類),從新渲染當前Activity。跳轉路徑是本地資源路徑 file://assets/dist/xxxx.js
  • iOs端,能夠正常使用navigator模塊(具體的跳起色制與Android不一樣,這塊我不太熟)。跳轉路徑是本地路徑 file://..../bundlejs/xxxx.js 或 hot reload的http://.../xxxx.js
weex提供的navigator模塊與event模塊都是響應跳轉路徑的,可是event應該是比較老的方式,由於放到了腳手架源碼中,反而能夠做爲本身開發的自定義模塊方便控制。但在Android的跳起色制上,是刷新Activity,而不是跳轉新的

腳手架native部分的源碼中,很大一部分是處理HotReload部分的,會致使與實際打包後引用業務js路徑不一樣小程序

統一封裝一個跳轉方法,實現區分代碼以下:

/**
 * 跳轉頁面
 *   根據傳入的跳轉相對路徑(/about、/views/user等),對三端區別處理,添加先後綴
 *   該方法能夠經過Vue.mixin()機制全局注入,但src/entry.js中Vue.mixin()沒法打包入weexjs,所以須要定義在src/lib/utils.js中
 * @param String url 要跳轉的地址
 */
export function jump (url) {
  let platform = weex.config.env.platform.toLowerCase();
  if (url.indexOf('/') === 0) {
    if (platform === 'web') {
      url += '.html'
    } else {
      url = weex.config.bundleUrl.replace(/\/(views\/.+|[^\/]+)\.js$/, url + '.js')
    }
  }
  if (platform === 'android') {
    // android中navigator會根據action+category區分,
    // 爲了防止多個weex應用呼起致使衝突,使用event模塊方式跳轉(顯式調用intent)
    const event = weex.requireModule('event')
    event.openURL(url)
  } else {
    const navigator = weex.requireModule('navigator')
    navigator.push({url: url, animated: "true"})
  }
}

有一個須要注意的地方,就是腳手架中Android實現代碼有bug,須要修復 WXPageActivity.java中 mUri 賦值問題,不然不管如何跳轉,最終都是獲取的初始加載頁面:

try {
  // 注意這裏添加了if塊:若是uri不是hot reload傳過來的對象,須要爲mUri賦值
  if (uri.toString().indexOf('{') != 0) {
    mUri = uri;
  }
  JSONObject initData = new JSONObject(uri.toString());
  ...

flex佈局問題

weex默認都是使用flex佈局,可是這個佈局使用,有必定的限制(僅描述我發現的,可能現象總結不許確)。

若是某個元素定義了 align-items:center,其下任意層級中再有flex佈局的組件,不指定高度時,Android沒法自動擴充(僅緊挨展示內容),iOs看不到渲染的內容。若是整個頁面都保持沒有這個特別的樣式定義,那麼Android是能夠正常實現flex佈局的自動擴充的。

寬高指定纔好安排內容。weex寬度上按750px縮放,可能有細微像素差異,問題不大。可視高度隨機型不一樣、虛擬按鍵和虛擬鍵盤收縮而不斷變動,若是能自動擴展填充,相對會好不少。可能有些問題是native自己就帶有的,好比虛擬鍵盤彈出,Android原生也是要作特別處理的。

weex-ui中不少組件,尤爲是容器組件(通常是帶有align-items樣式定義的)是要求必須指定高度的,其中的wxc-minibar一類的組件還會減去頂部大概64px的大小,用來計算可視高度,但在虛擬按鍵存在的機型上,明顯被遮擋部份內容。雖然有其餘方法一直保持動態計算,但這種方案要求對每一個容器都進行高度計算,對後期發展會形成很大的干擾。

歡迎嘗試保證整個應用都不設定具體的高度,有可能會帶來好的體驗。

樣式兼容問題

weex樣式是沒法簡寫的,雖然寫起來比較麻煩,倒也沒什麼可吐槽的地方。只是iOs不支持層級樣式,這點就比較奇葩了。

其餘一些樣式無效的都算小問題,就沒有特別記錄了,總有其餘方式替代(margin、padding增長空白相互替換等)。

登陸態保持

沒有cookie,沒法自動記錄,須要用到storage存儲來替代。

由於是多頁面,要注意每一個頁面都是同一套邏輯來檢查(check storage->check api)。習慣了單頁面總以爲很浪費資源。

組件擴展

按文檔作就行了,相對比較簡單。惟一須要注意的是native編寫完畢後,注意前端的js部分,也要把新組件註冊上。


這小半年中,小程序的文檔更新的都嫌太快,weex倒是一直這個樣子,更新最快的恐怕是weex的趟坑記錄吧。

相關文章
相關標籤/搜索