先說(shuō)結(jié)論,本人極度非常
不推薦weex作為任何商用開(kāi)發(fā)
有很多人會(huì)說(shuō)了... 你瞎扯.. 你看別人阿里.. 啊飛豬... 啊那個(gè)支付寶... 人家不是用得好好的么...
當(dāng)然這也是我們公司作為技術(shù)選型的考量.. 三端通用.. 阿里系的app全線在用.. 理論上是可以實(shí)現(xiàn)的.. 而且我們?cè)诰幋a過(guò)程中.. 可以把IOS工程師,安卓工程師和前端工程師以及部分熟悉一點(diǎn)前端的后端工程師都拉過(guò)來(lái)貢獻(xiàn)一套代碼.. 代碼質(zhì)量可以得到保障
現(xiàn)在想想只能說(shuō)... 太天真了... 你也不想想人家阿里有多少大牛有多少人在做這個(gè)項(xiàng)目.. 再說(shuō)淘寶都卡成啥樣了大家還是愿意用.. 如果你的項(xiàng)目這樣卡兩下你的app是否還能像淘寶那樣拉住顧客??
這就像你說(shuō)你想寫(xiě)一篇巨著... 你打算用英文寫(xiě)... 翻譯成中文 俄文 日文(ios android web)... 讓人看了還能把別人國(guó)家的感動(dòng)得稀里嘩啦的.. 本身難度就會(huì)不小..?
另外你在android中打開(kāi)布局邊界看一下天貓飛豬... 里面weex的界面已經(jīng)只剩下很少的界面了.. 很多界面已經(jīng)替換成了原生或者webview的混合界面... 做得那么雜用戶體驗(yàn)還過(guò)得去.. 我只能說(shuō)一句.. 阿里牛逼=.= ... 所以很明顯的一個(gè)信息就是.. 這個(gè)技術(shù)連他們自己人都不廣泛使用了.. 可見(jiàn)還是有很大的局限性的..
而且隨著項(xiàng)目持續(xù)增大.. weex項(xiàng)目的編譯時(shí)間會(huì)呈指數(shù)型上升.. 這樣的編碼體驗(yàn).. 說(shuō)糟糕都是在侮辱糟糕這個(gè)詞... 所以也請(qǐng)大家慎重考慮
如果你們已經(jīng)決定使用weex.. 或者正準(zhǔn)備用它構(gòu)建三端應(yīng)用... 那么.. 希望我的踩坑指南可以幫到你.. 從入門到放棄...
一.開(kāi)始準(zhǔn)備
搭建開(kāi)發(fā)環(huán)境
首先根據(jù)官網(wǎng)的提示安裝node.js weex-toolkit ?然后就可以開(kāi)始創(chuàng)建項(xiàng)目了.. 你可以選擇RN的rex 或者前端的VUE模式寫(xiě)代碼都是可以的.. 但是我們用的是vue.. rex也考慮過(guò).. 只是沒(méi)人會(huì)寫(xiě)RN.. 加上網(wǎng)上weex+RN的例子很少.. 所以就放棄了..?
如果是在windows上的話.. 安裝的東西都是需要配置環(huán)境變量的...?
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
分享一下我的環(huán)境變量里的東西.. node weex npm這些是必須要配置進(jìn)去的... 如果不配置的都是用不了的..?jupiter是我windows的用戶名 其他的大家自己看一下它給安裝到什么路徑下了.. 尤其是weex和weexpack是默認(rèn)的一個(gè)路徑 層級(jí)還很深.. 仔細(xì)找找配置進(jìn)去..
另外推薦個(gè)飛豬開(kāi)源的UI框架 weex-ui?
weex-ui
總體來(lái)說(shuō)這個(gè)UI框架還是能幫上一些忙的.. 但是里面本身就有些問(wèn)題.. 比如其中utils中的getPageHeight的高度.. 在web上是對(duì)的.. 但是手機(jī)上... emmmm... 會(huì)少一些高度.. 大約是88px... 原因不明.. 可能是android里面使用的默認(rèn)的toolbar... 但是他自動(dòng)幫你減掉了.. 但實(shí)際上沒(méi)有toolbar.. 這個(gè)高度就少了..
二.開(kāi)始踩坑
至于如何寫(xiě)vue代碼或者簡(jiǎn)單的helloworld.. 百度上都能查到... 我就不再贅述了.. 這里只說(shuō)些百度不到的坑或者舊坑解決方法已經(jīng)無(wú)效的問(wèn)題.. ?如果你覺(jué)得你會(huì)寫(xiě)vue到此就萬(wàn)事大吉了要開(kāi)始構(gòu)建三端應(yīng)用了... 那么我得先給你潑一盆冷水了... 大哥.. 你跳個(gè)界面給我看下..
1.界面跳轉(zhuǎn)
你會(huì)說(shuō):切 不就跳界面么.. 看我一手startActivi... vi...?
vi你個(gè)頭.. ?
在這里的跳轉(zhuǎn)需要使用navigator?去實(shí)現(xiàn).. 原理上這個(gè)東西是做了各端的特殊處理的.. 在web上比較像vue router.. 也就是單頁(yè)跳轉(zhuǎn).. 而在android上則是通過(guò)隱式去攔截對(duì)應(yīng)的url類型.. 如果是http和https開(kāi)頭的.. 會(huì)用webview去打開(kāi).. 如果是files開(kāi)頭的... 呵呵.. 你就發(fā)現(xiàn)它沒(méi)動(dòng)靜了...
這里再吐槽一手weex不適合商用的原因...?完全沒(méi)有社區(qū)... 這是最騷的... 所以遇到很多問(wèn)題只能自己去看源碼或者百度... 而且百度好多東西都是基于舊版本的.. 你用上就發(fā)現(xiàn).. 寫(xiě)得什么玩意 根本沒(méi)效果嘛..
跳轉(zhuǎn)就是我們遇到的第一個(gè)大坑.. 百度上都說(shuō).. 可以用vue router.. 然后我們?cè)嚵酥蟀l(fā)現(xiàn).. vue router在移動(dòng)端上根本不是真的界面跳轉(zhuǎn).. 只是一個(gè)單頁(yè)面.. 每次都重新加載.. 沒(méi)有跳轉(zhuǎn)動(dòng)畫(huà).. 這對(duì)于app的效果來(lái)說(shuō)是完全不能接受的..
而另一方面網(wǎng)上說(shuō)用navigator的實(shí)現(xiàn).. 在跳轉(zhuǎn)本地界面的時(shí)候都不生效..?
我們編碼的地方在src里.. 在使用npm build(npm run 或者weex run android等都會(huì)先build)后會(huì)生成一套JS文件存在dist里.. 而網(wǎng)上說(shuō)的只要用navigator打開(kāi)里面編譯生成的js文件就可以實(shí)現(xiàn)跳轉(zhuǎn).. 實(shí)際上打開(kāi)后.. 并不行..
那么在新版本的weex里要怎么做呢.. 我們?cè)嚵撕镁煤?. 受到首頁(yè)的地址是index.html的啟發(fā).. 發(fā)現(xiàn)使用src對(duì)應(yīng)目錄下的vue文件地址把后綴改成html即可實(shí)現(xiàn)web跳轉(zhuǎn)... 比如你首頁(yè)的地址是http://192.168.2.17:8081/index.html... 那么你需要打開(kāi)components下的home.vue界面 ?那地址就是 http://192.168.2.17:8081/components/home.html ... 網(wǎng)頁(yè)跳轉(zhuǎn)正常了 .. 當(dāng)我們歡呼雀躍準(zhǔn)備繼續(xù)時(shí).. 發(fā)現(xiàn)手機(jī)上又跳不了...?在項(xiàng)目目錄下運(yùn)行
weex platform add android
你的項(xiàng)目就可以用 weex run android運(yùn)行在安卓手機(jī)上了...?
網(wǎng)上好多說(shuō)需要找到本地資源文件夾下的地址即可跳轉(zhuǎn).. 在android中.. 確實(shí)發(fā)現(xiàn)assets文件夾下有這些界面的js文件..?
只要用 file://assets/dist/在安卓中找到這個(gè)文件跳轉(zhuǎn)就可以了.. 然后再次發(fā)現(xiàn)是無(wú)效的.. 但是發(fā)現(xiàn)跳轉(zhuǎn)http和https在手機(jī)上是有效的.. 那么也就是說(shuō)隱式調(diào)用沒(méi)有攔截到這file這個(gè)請(qǐng)求..
但是明明在android項(xiàng)目的manifast里是已經(jīng)在攔截file的.. 最后發(fā)現(xiàn)確實(shí)file是攔截不到的.. 其他什么關(guān)鍵字都可以.. 那么怎么辦呢.. 最后我只能在地址前面加上別的關(guān)鍵字local 但是讓隱式攔截local關(guān)鍵字.. 最后再activity里再把local給去掉 用file地址去渲染..
最終獲取三端對(duì)應(yīng)跳轉(zhuǎn)地址的方法 (注意安卓中前面添加了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是直接跳轉(zhuǎn)到新頁(yè)面上的.
if (typeof window === 'object') {
nativeBase = 'http://' + host + '/';
} else {
nativeBase = 'http://' + host + '/';
}
native = nativeBase + toUrl + ".html";
}
return native;
}
android manifest 中攔截local
android java code中把local頭給去掉 拿file地址去渲染
把local關(guān)鍵字給替換掉.. 然后其他的和原來(lái)操作一樣
這樣在android上的跳轉(zhuǎn)才算解決了
如果你看到這個(gè)坑就已經(jīng)準(zhǔn)備放棄了.. 我只能說(shuō).. 施主 回頭是岸.. 如果你覺(jué)得還想挑戰(zhàn)一下.. 那么繼續(xù)看后面的坑吧..
2.控件太少 基本只能實(shí)現(xiàn)最基本的效果
第二個(gè)大坑就是控件過(guò)于少.. 很多效果在weex中你是沒(méi)法實(shí)現(xiàn)的.. 或者說(shuō)不是一般人可以實(shí)現(xiàn)的... 除非你是真的精通三端的技術(shù)大牛.. 不然你要掂量一下自己的項(xiàng)目.. 是不是有地圖.. 是不是有其他動(dòng)畫(huà).. 是不是有weex-ui中沒(méi)有的效果.. 如果有.. 那么是否有替代方案或者對(duì)UI的要求高不高..能不能接受替換.. 是否有自己封裝控件的經(jīng)驗(yàn)..
就算你要自己做.. 還有一個(gè)事情你必須知道..
那就是
什么意思呢.. 就是說(shuō)滑動(dòng)事件獲取是不靠譜的.. 甚至在weex-ui的slide-nav(視窗增大)中看到了類似的備注
之前還考慮過(guò)希望封裝個(gè)類似ios picker的效果... 看到這個(gè)之后就放棄了.. 滑動(dòng)事件的監(jiān)聽(tīng)都不靠譜的話.. 很多效果就算要自己封裝也是不太可能呢..
3.滾動(dòng)控件滑不動(dòng)
在weex 中提供了好多種滾動(dòng)控件 包括list scroller 但是一開(kāi)始使用的時(shí)候發(fā)現(xiàn)都滑不動(dòng)... 后來(lái)才發(fā)現(xiàn).. 如果不給這些控件指定高度.. 那么它會(huì)包裹內(nèi)容高度.. 那么內(nèi)容高度和控件高度相同也就不可以滑動(dòng)了... 控件已經(jīng)頂出屏幕了你也不知道.. 那么對(duì)于這些滾動(dòng)控件是必須指定高度的... 但是高度怎么拿呢...
weex的規(guī)則是屏幕寬度是750px 而高度是根據(jù)寬高比算出來(lái)的.. 也就是高度是不固定的.. weex-ui中的utils中有獲取屏幕高度的方法.. 但是就是開(kāi)頭提到的問(wèn)題.. android上回少88px;
所以只能自己封裝個(gè)獲取高度的方法
import {Utils} from 'weex-ui'
const screenHeight = Utils.env.getPageHeight() ;
const androidNavHeight = Utils.env.isAndroid() ? 88 : 0;
return screenHeight +androidNavHeight;
用這樣的方法獲取的高度.. 再設(shè)置給scroller才可以使用.. 當(dāng)然如果你的界面里還有其他控件.. 高度還要再減去那些.. 不然scroller會(huì)包裹內(nèi)容高度..
4.前端代碼不是全部可靠的
在官網(wǎng)上寫(xiě)出了幾種不支持的樣式, 百分比是不支持的.. 包括我之前用的border 50% 去繪制圓形.. 到app上會(huì)變成50px.. 另外用border繪制三角形之類的都是不可靠的.. 在web上可以實(shí)現(xiàn).. 到手機(jī)上就雪崩了.. 所以如果你是前端過(guò)來(lái)的同學(xué).. 不要什么vue的騷操作都往里套.. 它并不是真正意義上的前端代碼.. 所以還要對(duì)不同系統(tǒng)去調(diào)整適配問(wèn)題... 所以你的團(tuán)隊(duì)中最少的需要有三端都懂的人才可以用.. 而不是說(shuō)你懂前端就悶頭寫(xiě).. 最后web沒(méi)問(wèn)題了.. 在android和ios上都運(yùn)行不起來(lái).. 最后debug都不知道從哪做起... 展開(kāi)記錄一下那些寫(xiě)法是不可以的..
4.1.dom document對(duì)象不可用
在前端中也許會(huì)有類似
var mo = function(e) {
e.preventDefault();
};
document.body.style.overflow = 'hidden';
document.addEventListener("touchmove", mo, false); //禁止頁(yè)面滑動(dòng)
的代碼來(lái)實(shí)現(xiàn)禁止頁(yè)面滑動(dòng).. 在網(wǎng)頁(yè)中如果內(nèi)容超過(guò)了瀏覽器高度便可以滑動(dòng).. 如果你想禁用掉這個(gè)滑動(dòng)便會(huì)涉及到以上的代碼.. 但是這個(gè)代碼在手機(jī)上會(huì)報(bào)?render error:-2024
實(shí)際上就是js中找不到這個(gè)對(duì)象.. 所以這個(gè)寫(xiě)法是不可用的
另外.. 所有的類似空指針的操作.. 在網(wǎng)頁(yè)上是可以顯示的.. 但是在android中.. 會(huì)報(bào)出上面所說(shuō)的render error:-2024的錯(cuò)誤... 而且不知道如何定位這個(gè)錯(cuò)誤在哪.. 所以解決報(bào)錯(cuò)也是個(gè)比較頭疼的問(wèn)題.. 最好拿每天的代碼都跑一下手機(jī)看看是否有類似報(bào)錯(cuò).. 不然層級(jí)太多了都不知道這個(gè)錯(cuò)是哪里來(lái)的...
4.2.css代碼如百分比不可用
在前端中畫(huà)圓你可能會(huì)用到 border-width:50% 這樣的代碼來(lái)實(shí)現(xiàn)一個(gè)節(jié)點(diǎn)的圓形... 但是這在手機(jī)上也是不可用的... weex官網(wǎng)上有解釋.. 類似width這種傳數(shù)字的無(wú)論你傳什么單位都會(huì)被轉(zhuǎn)成px ... 所以以上代碼的實(shí)際效果就是50px的圓角了... 如果要實(shí)現(xiàn)圓形.. 還是要自己傳定死的半徑進(jìn)去..
具體還有不可用的css寫(xiě)法參考 : ??css支持
4.3.list中必須使用cell標(biāo)簽才可以顯示
在網(wǎng)頁(yè)中.. list中的布局無(wú)論放什么都是可以正常展示的.. 但是在手機(jī)中... 不用
4.4.很多標(biāo)簽在手機(jī)上不支持部分基礎(chǔ)css屬性
現(xiàn)在發(fā)現(xiàn)的主要是在android上margin屬性在
講道理margin這種基礎(chǔ)css屬性應(yīng)該在所有標(biāo)簽上都是生效的.. 但是實(shí)際卻不是.. 文檔中也沒(méi)有相關(guān)提示
5.vue的mvvm控件內(nèi)部雙向綁定問(wèn)題
vue對(duì)于前端的同學(xué)可能不會(huì)陌生... 這是一個(gè)類似mvvm思想的框架,也就是說(shuō).. 視圖直接和數(shù)據(jù)綁定了... 在數(shù)據(jù)改變時(shí)直接改變控件對(duì)應(yīng)的視圖狀態(tài),如下
前面也說(shuō)過(guò)weex是用vue完成代碼再在手機(jī)上去用原生控件渲染的...
但是vue中會(huì)涉及到一個(gè)內(nèi)部控件去改外部參數(shù)的問(wèn)題...如?點(diǎn)擊打開(kāi)鏈接
控件內(nèi)部希望修改props中傳進(jìn)來(lái)的參數(shù)去控制外部狀態(tài)時(shí).. 會(huì)報(bào)出?[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"(參數(shù)名)?
然后外部參數(shù)并沒(méi)有改變.. 只是內(nèi)部的變量改變了..
那么怎么辦呢.. 其實(shí)在vue中可以傳入對(duì)象作為參數(shù)... 而props中的參數(shù)是不可變的.. 也就是傳入的對(duì)象是不可被改變的 但是對(duì)象中的參數(shù)是可變的..
我的做法就是傳入data整個(gè)對(duì)象.. 里面包含了checkPosition屬性... 這樣就可以在js中對(duì)外部的屬性進(jìn)行修改了
6.android中picasso版本太舊導(dǎo)致部分https地址圖片加載有問(wèn)題
在android項(xiàng)目中對(duì)image標(biāo)簽中的地址圖片.. 實(shí)際上是在用picasso加載的.. 但是它的版本已經(jīng)比較舊了.. 好像是2.5.2的... 之前還以為是服務(wù)器上的圖片處理有問(wèn)題.. ?后來(lái)在排錯(cuò)之后發(fā)現(xiàn)是picasso舊版本對(duì)https支持不太好 ... 只要把舊版本的picasso升級(jí).. 再extend下的ImageAdapter的代碼用picasso的新版api加載圖片.. 就可以解決這個(gè)問(wèn)題了.. 不過(guò)也許你也遇不到這個(gè)問(wèn)題.. 并不是所有的https下的圖片都不可加載..
7.血坑!! 編譯速度過(guò)慢
這個(gè)是最近才越來(lái)越明顯感受到的一個(gè)問(wèn)題.. 隨著項(xiàng)目變大.. 編譯速度會(huì)指數(shù)型上升.. 前期編譯一下幾秒.. 后來(lái)編譯一下半分鐘... 現(xiàn)在項(xiàng)目基本沒(méi)五分鐘跑不起來(lái)了.. 而且項(xiàng)目是沒(méi)有布局預(yù)覽的.. 也就是說(shuō)你改一下布局想看看效果..就要付出五分鐘的代價(jià).. 太痛苦了.. 這個(gè)應(yīng)該作為團(tuán)隊(duì)技術(shù)選型時(shí)的重要考慮點(diǎn).. 是否真的為了不是很完美的三端通用.. 去浪費(fèi)茫茫多的編譯時(shí)間...
解決:后來(lái)發(fā)現(xiàn)在安卓手機(jī)編譯的速度會(huì)比較快一些.. 大約30秒左右... 算是可以接受吧... 起碼比五分鐘好多了..
三.結(jié)論
暫時(shí)遇到的坑就這些 .. 但是還是那句話..
別拿weex來(lái)做商用!! 坑太多!!!
我這個(gè)項(xiàng)目已經(jīng)入坑了只能硬著頭皮做下去.. 后面有新坑我還會(huì)回來(lái)更新的..
比較完整的學(xué)習(xí)項(xiàng)目目前只找到
網(wǎng)易嚴(yán)選demo
這個(gè)項(xiàng)目是用vue router做的跳轉(zhuǎn).. 沒(méi)有用navigator實(shí)現(xiàn)真正的多頁(yè)應(yīng)用.. 不過(guò)里面的vue+js+css代碼還是有很多可以參考的地方的...
四.后記
最終還是和老大商量用安卓原生重做整個(gè)app了... 如大家所見(jiàn).. 上面茫茫多的問(wèn)題.. 記錄一下我們竭盡所能仍未解決的一些問(wèn)題吧.. 希望大家引以為戒..
1.入口如何修改?
在目錄中就一個(gè)index文件作為入口.. 但是對(duì)于app來(lái)說(shuō)應(yīng)該會(huì)有所判斷的.. 如區(qū)分有token和沒(méi)有token的情況... 但是始終沒(méi)有找到如何修改或能判斷入口的地方..
2.兼容性問(wèn)題巨大
在安卓4.4上.. 某些文字在離開(kāi)界面再返回時(shí)直接會(huì)不見(jiàn)... 而高度在安卓上也會(huì)亂跳... (之前提到的減去88px并不是可靠的).. 因?yàn)闈L動(dòng)控件必須要限定邊界... 所以逐漸就沒(méi)有很好的解決方案了..
3.模板內(nèi)部的點(diǎn)擊和滾動(dòng)事件失效
在component內(nèi)部分點(diǎn)擊和滾動(dòng)事件直接無(wú)響應(yīng).. scroller中的布局也從水平的變成豎直的了...(在網(wǎng)頁(yè)中都是正常的)... 現(xiàn)在已經(jīng)決定放棄這個(gè)框架了也就懶得去排錯(cuò)了... 反正就是布局和手勢(shì)在component中引用會(huì)有很大的問(wèn)題...
4.沒(méi)有很好的debug手段
由于他的代碼在手機(jī)和網(wǎng)頁(yè)中并不是都可用的... 所以難免在手機(jī)中會(huì)報(bào)很多錯(cuò).. 但是錯(cuò)誤會(huì)直接在界面上寫(xiě)個(gè)render error:-2024就停止執(zhí)行了.. 完全看不到錯(cuò)誤提示.. 也沒(méi)有debug模式.. 在網(wǎng)頁(yè)中又好端端的... 所以遇到一個(gè)小錯(cuò)就是半小時(shí)一小時(shí).. 如此時(shí)間成本.. 做出來(lái)一個(gè)項(xiàng)目怕已經(jīng)到了明年..
本次weex的探索之旅就到此結(jié)束了... 所以不穩(wěn)定的技術(shù)真的不要瞎用.. 代價(jià)很大..
原文發(fā)布時(shí)間:2024年04月21日 12:47:10
原文作者:Jupiterxx
本文來(lái)源CSDN,如需轉(zhuǎn)載請(qǐng)聯(lián)系原作者