天天看點

【CSDN軟體工程師能力認證學習精選】weex踩坑指南(weex navigator 多界面跳轉)

CSDN軟體工程師能力認證(以下簡稱C系列認證)是由中國軟體開發者網CSDN制定并推出的一個能力認證标準。C系列認證曆經近一年的實際線下調研、考察、疊代、測試,并梳理出軟體工程師開發過程中所需的各項技術技能,結合企業招聘需求和人才應聘痛點,基于公開、透明、公正的原則,甑别人才時確定真實業務場景、全部上機實操、所有過程留痕、存檔不可篡改。

我們每天将都會精選CSDN站内技術文章供大家學習,幫助大家系統化學習IT技術。

一.開始準備

搭建開發環境

首先根據官網的提示安裝node.js weex-toolkit  然後就可以開始建立項目了.. 你可以選擇RN的rex 或者前端的VUE模式寫代碼都是可以的.. 但是我們用的是vue.. rex也考慮過.. 隻是沒人會寫RN.. 加上網上weex+RN的例子很少.. 是以就放棄了.. 

如果是在windows上的話.. 安裝的東西都是需要配置環境變量的... 

D:\nodeJs\npm;D:\nodeJs\node.exe;C:\Users\jupiter\AppData\Roaming\npm;C:\Users\jupiter\AppData\Roaming\npm\node_modules\weex-toolkit\bin\weex.js;C:\Users\jupiter\AppData\Roaming\npm\node_modules\weexpack\bin\weexpack.js;C:\Users\jupiter\AppData\Roaming\npm\node_modules\weex-toolkit\node_modules\weex-previewer\vue-template\template\assets\vue.js

分享一下我的環境變量裡的東西.. node weex npm這些是必須要配置進去的... 如果不配置的都是用不了的.. jupiter是我windows的使用者名 其他的大家自己看一下它給安裝到什麼路徑下了.. 尤其是weex和weexpack是預設的一個路徑 層級還很深.. 仔細找找配置進去..

另外推薦個飛豬開源的UI架構 weex-ui 

weex-ui

總體來說這個UI架構還是能幫上一些忙的.. 但是裡面本身就有些問題.. 比如其中utils中的getPageHeight的高度.. 在web上是對的.. 但是手機上... emmmm... 會少一些高度.. 大約是88px... 原因不明.. 可能是android裡面使用的預設的toolbar... 但是他自動幫你減掉了.. 但實際上沒有toolbar.. 這個高度就少了..

二.開始踩坑

至于如何寫vue代碼或者簡單的helloworld.. 百度上都能查到... 我就不再贅述了.. 這裡隻說些百度不到的坑或者舊坑解決方法已經無效的問題..  如果你覺得你會寫vue到此就萬事大吉了要開始建構三端應用了... 那麼我得先給你潑一盆冷水了... 大哥.. 你跳個界面給我看下..

1.界面跳轉

你會說:切 不就跳界面麼.. 看我一手startActivi... vi... 

vi你個頭..  

在這裡的跳轉需要使用navigator 去實作.. 原理上這個東西是做了各端的特殊處理的.. 在web上比較像vue router.. 也就是單頁跳轉.. 而在android上則是通過隐式去攔截對應的url類型.. 如果是http和https開頭的.. 會用webview去打開.. 如果是files開頭的... 呵呵.. 你就發現它沒動靜了...

這裡再吐槽一手weex不适合商用的原因... 完全沒有社群... 這是最騷的... 是以遇到很多問題隻能自己去看源碼或者百度... 而且百度好多東西都是基于舊版本的.. 你用上就發現.. 寫得什麼玩意 根本沒效果嘛..

跳轉就是我們遇到的第一個大坑.. 百度上都說.. 可以用vue router.. 然後我們試了之後發現.. vue router在移動端上根本不是真的界面跳轉.. 隻是一個單頁面.. 每次都重新加載.. 沒有跳轉動畫.. 這對于app的效果來說是完全不能接受的..

而另一方面網上說用navigator的實作.. 在跳轉本地界面的時候都不生效.. 

【CSDN軟體工程師能力認證學習精選】weex踩坑指南(weex navigator 多界面跳轉)

我們編碼的地方在src裡.. 在使用npm build(npm run 或者weex run android等都會先build)後會生成一套JS檔案存在dist裡.. 而網上說的隻要用navigator打開裡面編譯生成的js檔案就可以實作跳轉.. 實際上打開後.. 并不行..

那麼在新版本的weex裡要怎麼做呢.. 我們試了好久後.. 受到首頁的位址是index.html的啟發.. 發現使用src對應目錄下的vue檔案位址把字尾改成html即可實作web跳轉... 比如你首頁的位址是http://192.168.2.17:8081/index.html... 那麼你需要打開components下的home.vue界面  那位址就是 http://192.168.2.17:8081/components/home.html ...

網頁跳轉正常了 .. 當我們歡呼雀躍準備繼續時.. 發現手機上又跳不了... 

在項目目錄下運作

weex platform add android
           

你的項目就可以用 weex run android運作在安卓手機上了... 

網上好多說需要找到本地資源檔案夾下的位址即可跳轉.. 在android中.. 确實發現assets檔案夾下有這些界面的js檔案.. 

【CSDN軟體工程師能力認證學習精選】weex踩坑指南(weex navigator 多界面跳轉)

隻要用 file://assets/dist/在安卓中找到這個檔案跳轉就可以了.. 然後再次發現是無效的.. 但是發現跳轉http和https在手機上是有效的.. 那麼也就是說隐式調用沒有攔截到這file這個請求..

【CSDN軟體工程師能力認證學習精選】weex踩坑指南(weex navigator 多界面跳轉)

但是明明在android項目的manifast裡是已經在攔截file的.. 最後發現确實file是攔截不到的.. 其他什麼關鍵字都可以.. 那麼怎麼辦呢.. 最後我隻能在位址前面加上别的關鍵字local 但是讓隐式攔截local關鍵字.. 最後再activity裡再把local給去掉 用file位址去渲染..

最終擷取三端對應跳轉位址的方法 (注意安卓中前面添加了local是為了給攔截)

getJumpBaseUrl(toUrl) {
 
        var bundleUrl = weex.config.bundleUrl;
 
        var isnav = true
        bundleUrl = new String(bundleUrl);
        var nativeBase;
        var native;
        var isAndroidAssets = bundleUrl.indexOf('file://assets/') >= 0;
        var isiOSAssets = bundleUrl.indexOf('file:///') >= 0 && bundleUrl.indexOf('WeexDemo.app') > 0;
        if (isAndroidAssets) {
            nativeBase = "local://" + 'file://assets/dist/';
            native = nativeBase + toUrl + ".js";
        } else if (isiOSAssets) {
            nativeBase = bundleUrl.substring(0, bundleUrl.lastIndexOf('/') + 1);
            native = nativeBase + toUrl + ".js";
        } else {
            var host = 'localhost:8081';
            var matches = /\/\/([^\/]+?)\//.exec(bundleUrl);
            if (matches && matches.length >= 2) {
                host = matches[1];
            }
 
            //此處需注意一下,tabbar 用的直接是jsbundle 的路徑,但是navigator是直接跳轉到新頁面上的.
            if (typeof window === 'object') {
                nativeBase = 'http://' + host + '/';
            } else {
                nativeBase = 'http://' + host + '/';
            }
 
            native = nativeBase + toUrl + ".html";
        }
        return native;
    }
           

android manifest 中攔截local

getJumpBaseUrl(toUrl) {
 
        var bundleUrl = weex.config.bundleUrl;
 
        var isnav = true
        bundleUrl = new String(bundleUrl);
        var nativeBase;
        var native;
        var isAndroidAssets = bundleUrl.indexOf('file://assets/') >= 0;
        var isiOSAssets = bundleUrl.indexOf('file:///') >= 0 && bundleUrl.indexOf('WeexDemo.app') > 0;
        if (isAndroidAssets) {
            nativeBase = "local://" + 'file://assets/dist/';
            native = nativeBase + toUrl + ".js";
        } else if (isiOSAssets) {
            nativeBase = bundleUrl.substring(0, bundleUrl.lastIndexOf('/') + 1);
            native = nativeBase + toUrl + ".js";
        } else {
            var host = 'localhost:8081';
            var matches = /\/\/([^\/]+?)\//.exec(bundleUrl);
            if (matches && matches.length >= 2) {
                host = matches[1];
            }
 
            //此處需注意一下,tabbar 用的直接是jsbundle 的路徑,但是navigator是直接跳轉到新頁面上的.
            if (typeof window === 'object') {
                nativeBase = 'http://' + host + '/';
            } else {
                nativeBase = 'http://' + host + '/';
            }
 
            native = nativeBase + toUrl + ".html";
        }
        return native;
    }
           

android java code中把local頭給去掉 拿file位址去渲染

【CSDN軟體工程師能力認證學習精選】weex踩坑指南(weex navigator 多界面跳轉)

把local關鍵字給替換掉.. 然後其他的和原來操作一樣

這樣在android上的跳轉才算解決了

如果你看到這個坑就已經準備放棄了.. 我隻能說.. 施主 回頭是岸.. 如果你覺得還想挑戰一下.. 那麼繼續看後面的坑吧..

2.控件太少 基本隻能實作最基本的效果

第二個大坑就是控件過于少.. 很多效果在weex中你是沒法實作的.. 或者說不是一般人可以實作的... 除非你是真的精通三端的技術大牛.. 不然你要掂量一下自己的項目.. 是不是有地圖.. 是不是有其他動畫.. 是不是有weex-ui中沒有的效果.. 如果有.. 那麼是否有替代方案或者對UI的要求高不高..能不能接受替換.. 是否有自己封裝控件的經驗..

就算你要自己做.. 還有一個事情你必須知道..

那就是

【CSDN軟體工程師能力認證學習精選】weex踩坑指南(weex navigator 多界面跳轉)

什麼意思呢.. 就是說滑動事件擷取是不靠譜的.. 甚至在weex-ui的slide-nav(視窗增大)中看到了類似的備注

【CSDN軟體工程師能力認證學習精選】weex踩坑指南(weex navigator 多界面跳轉)

之前還考慮過希望封裝個類似ios picker的效果... 看到這個之後就放棄了.. 滑動事件的監聽都不靠譜的話.. 很多效果就算要自己封裝也是不太可能呢..

3.滾動控件滑不動

在weex 中提供了好多種滾動控件 包括list scroller 但是一開始使用的時候發現都滑不動... 後來才發現.. 如果不給這些控件指定高度.. 那麼它會包裹内容高度.. 那麼内容高度和控件高度相同也就不可以滑動了... 控件已經頂出螢幕了你也不知道.. 那麼對于這些滾動控件是必須指定高度的... 但是高度怎麼拿呢...

weex的規則是螢幕寬度是750px 而高度是根據寬高比算出來的.. 也就是高度是不固定的.. weex-ui中的utils中有擷取螢幕高度的方法.. 但是就是開頭提到的問題.. android上回少88px;

是以隻能自己封裝個擷取高度的方法

import {Utils} from 'weex-ui'       
 
 const screenHeight = Utils.env.getPageHeight() ;
        const androidNavHeight =  Utils.env.isAndroid() ? 88 : 0;
        return screenHeight +androidNavHeight;
           

用這樣的方法擷取的高度.. 再設定給scroller才可以使用.. 當然如果你的界面裡還有其他控件.. 高度還要再減去那些.. 不然scroller會包裹内容高度..

4.前端代碼不是全部可靠的

在官網上寫出了幾種不支援的樣式, 百分比是不支援的.. 包括我之前用的border 50% 去繪制圓形.. 到app上會變成50px.. 另外用border繪制三角形之類的都是不可靠的.. 在web上可以實作.. 到手機上就雪崩了.. 是以如果你是前端過來的同學.. 不要什麼vue的騷操作都往裡套.. 它并不是真正意義上的前端代碼.. 是以還要對不同系統去調整适配問題... 是以你的團隊中最少的需要有三端都懂的人才可以用.. 而不是說你懂前端就悶頭寫.. 最後web沒問題了.. 在android和ios上都運作不起來.. 最後debug都不知道從哪做起... 展開記錄一下那些寫法是不可以的..

4.1.dom document對象不可用

在前端中也許會有類似

var mo = function(e) {
            e.preventDefault();
         };
         document.body.style.overflow = 'hidden';
         document.addEventListener("touchmove", mo, false); //禁止頁面滑動
           

的代碼來實作禁止頁面滑動.. 在網頁中如果内容超過了浏覽器高度便可以滑動.. 如果你想禁用掉這個滑動便會涉及到以上的代碼.. 但是這個代碼在手機上會報 render error:-2013

實際上就是js中找不到這個對象.. 是以這個寫法是不可用的

另外.. 所有的類似空指針的操作.. 在網頁上是可以顯示的.. 但是在android中.. 會報出上面所說的render error:-2013的錯誤... 而且不知道如何定位這個錯誤在哪.. 是以解決報錯也是個比較頭疼的問題.. 最好拿每天的代碼都跑一下手機看看是否有類似報錯.. 不然層級太多了都不知道這個錯是哪裡來的...

4.2.css代碼如百分比不可用

在前端中畫圓你可能會用到 border-width:50% 這樣的代碼來實作一個節點的圓形... 但是這在手機上也是不可用的... weex官網上有解釋.. 類似width這種傳數字的無論你傳什麼機關都會被轉成px ... 是以以上代碼的實際效果就是50px的圓角了... 如果要實作圓形.. 還是要自己傳定死的半徑進去..

具體還有不可用的css寫法參考 :   css支援

4.3.list中必須使用cell标簽才可以顯示

在網頁中.. list中的布局無論放什麼都是可以正常展示的.. 但是在手機中... 不用<cell> 包裹的話.. 内容是不予展示的.. 這樣設計的考慮可能是涉及到一個複用機制... 在手機中無論是IOS的TableView還是android的listview Recyclerview中的item都是要複用的.. 不然在手機中反複生成item會導緻oom.. 是以cell包裹的内容會被複用.. 沒被cell包裹的将不會被複用.. 且在list中不顯示.. 主要是防止未複用的item過多導緻oom是以強制使用的吧

4.4.很多标簽在手機上不支援部分基礎css屬性

現在發現的主要是在android上margin屬性在<cell>标簽中是無效的.. 是以要使用margin需要在cell中再使用div包裹一層.. 

講道理margin這種基礎css屬性應該在所有标簽上都是生效的.. 但是實際卻不是.. 文檔中也沒有相關提示

5.vue的mvvm控件内部雙向綁定問題

vue對于前端的同學可能不會陌生... 這是一個類似mvvm思想的架構,也就是說.. 視圖直接和資料綁定了... 在資料改變時直接改變控件對應的視圖狀态,如下

【CSDN軟體工程師能力認證學習精選】weex踩坑指南(weex navigator 多界面跳轉)

前面也說過weex是用vue完成代碼再在手機上去用原生控件渲染的...

但是vue中會涉及到一個内部控件去改外部參數的問題...

控件内部希望修改props中傳進來的參數去控制外部狀态時.. 會報出 [Vue warn]: Avoid mutating a prop directly since the value will be overwritten whenever the parent component re-renders. Instead, use a data or computed property based on the prop's value. Prop being mutated: "xxxx"(參數名) 

然後外部參數并沒有改變.. 隻是内部的變量改變了..

那麼怎麼辦呢.. 其實在vue中可以傳入對象作為參數... 而props中的參數是不可變的.. 也就是傳入的對象是不可被改變的 但是對象中的參數是可變的..

【CSDN軟體工程師能力認證學習精選】weex踩坑指南(weex navigator 多界面跳轉)

我的做法就是傳入data整個對象.. 裡面包含了checkPosition屬性... 這樣就可以在js中對外部的屬性進行修改了

6.android中picasso版本太舊導緻部分https位址圖檔加載有問題

在android項目中對image标簽中的位址圖檔.. 實際上是在用picasso加載的.. 但是它的版本已經比較舊了.. 好像是2.5.2的... 之前還以為是伺服器上的圖檔處理有問題..  後來在排錯之後發現是picasso舊版本對https支援不太好 ... 隻要把舊版本的picasso更新.. 再extend下的ImageAdapter的代碼用picasso的新版api加載圖檔.. 就可以解決這個問題了.. 不過也許你也遇不到這個問題.. 并不是所有的https下的圖檔都不可加載..

7.血坑!! 編譯速度過慢

這個是最近才越來越明顯感受到的一個問題.. 随着項目變大.. 編譯速度會指數型上升.. 前期編譯一下幾秒.. 後來編譯一下半分鐘... 現在項目基本沒五分鐘跑不起來了.. 而且項目是沒有布局預覽的.. 也就是說你改一下布局想看看效果..就要付出五分鐘的代價.. 太痛苦了.. 這個應該作為團隊技術選型時的重要考慮點.. 是否真的為了不是很完美的三端通用.. 去浪費茫茫多的編譯時間...

解決:後來發現在安卓手機編譯的速度會比較快一些.. 大約30秒左右... 算是可以接受吧... 起碼比五分鐘好多了..

三.結論

暫時遇到的坑就這些 .. 但是還是那句話..

别拿weex來做商用!! 坑太多!!!

我這個項目已經入坑了隻能硬着頭皮做下去.. 後面有新坑我還會回來更新的..

比較完整的學習項目目前隻找到

網易嚴選demo

這個項目是用vue router做的跳轉.. 沒有用navigator實作真正的多頁應用.. 不過裡面的vue+js+css代碼還是有很多可以參考的地方的...

四.後記

最終還是和老大商量用安卓原生重做整個app了... 如大家所見.. 上面茫茫多的問題.. 記錄一下我們竭盡所能仍未解決的一些問題吧.. 希望大家引以為戒..

1.入口如何修改?

在目錄中就一個index檔案作為入口.. 但是對于app來說應該會有所判斷的.. 如區分有token和沒有token的情況... 但是始終沒有找到如何修改或能判斷入口的地方..

2.相容性問題巨大

在安卓4.4上.. 某些文字在離開界面再傳回時直接會不見... 而高度在安卓上也會亂跳... (之前提到的減去88px并不是可靠的).. 因為滾動控件必須要限定邊界... 是以逐漸就沒有很好的解決方案了..

3.模闆内部的點選和滾動事件失效

在component内部分點選和滾動事件直接無響應.. scroller中的布局也從水準的變成豎直的了...(在網頁中都是正常的)... 現在已經決定放棄這個架構了也就懶得去排錯了... 反正就是布局和手勢在component中引用會有很大的問題...

4.沒有很好的debug手段

由于他的代碼在手機和網頁中并不是都可用的... 是以難免在手機中會報很多錯.. 但是錯誤會直接在界面上寫個render error:-2013就停止執行了.. 完全看不到錯誤提示.. 也沒有debug模式.. 在網頁中又好端端的... 是以遇到一個小錯就是半小時一小時.. 如此時間成本.. 做出來一個項目怕已經到了明年..

————————————————

關于CSDN軟體工程師能力認證

      CSDN軟體工程師能力認證(以下簡稱C系列認證)是由中國軟體開發者網CSDN制定并推出的一個能力認證标準。C系列認證曆經近一年的實際線下調研、考察、疊代、測試,并梳理出軟體工程師開發過程中所需的各項技術技能,結合企業招聘需求和人才應聘痛點,基于公開、透明、公正的原則,甑别人才時確定真實業務場景、全部上機實操、所有過程留痕、存檔不可篡改。C系列認證的宗旨是讓一流的技術人才憑真才實學進大廠拿高薪,同時為企業節約大量招聘與培養成本,使命是提升高校大學生的技術能力,為行業提供人才儲備,為國家數字化戰略貢獻力量。

了解詳情可點選:CSDN軟體工程師能力認證介紹

原文連結:https://blog.csdn.net/Jupiterxx/article/details/80026909

繼續閱讀