1短蜕、Weex的由來
WEEX前身
Weex的前身是WeApp,一個用JSON配置原生UI組件來實現動態(tài)化的框架鹏溯,Weex是WeApp的進化版本捏萍,加上ex去掉App太抓,就成了現在這個名字。
與Vue.js的關系
如果對前端有所涉獵的同學會發(fā)現令杈,Weex的DSL風格與一個前端的MVVM框架Vue.js比較像走敌,那么它們的關系是什么呢?
Weex由多個關鍵模塊組成逗噩,分別是DSL transformer掉丽、JS Framework、HTML5/iOS/Android Renderer和工具鏈 异雁, 其中JS Framework就直接使用了部分來自Vue.JS的代碼捶障。不過這種使用也是遵守開源協(xié)議的(Vue使用MIT協(xié)議,Weex使用Apache協(xié)議)纲刀,Weex團隊在源碼的說明文件中記錄了來自Vue.JS和其他開源項目的貢獻
2项炼、Weex工作原理
1、DSL : weex文件示绊;
2锭部、Virtual DOM (提升性能) :
Virtual DOM 是一個模擬 DOM 樹的 JavaScript 對象。 weex使用 Virtual DOM 來渲染 UI面褐,當組件狀態(tài)state 有更改的時候拌禾,weex會自動調用組件的 render 方法重新渲染整個組件的 UI。
weex主要的目標是提供一套不同的, 高效的方案來更新 DOM.不是通過直接把 DOM 變成可變的數據, 而是通過構建 “Virtual DOM”, 虛擬的 DOM, 隨后 weex處理真實的 DOM 上的更新來進行模擬相應的更新展哭。
DOM 樹上的節(jié)點被稱為元素, 而 virtual DOM 是完全不同的抽象, 叫做 components湃窍,component 的使用在 weex里極為重要, 因為 components 的存在讓計算 DOM diff 更高效闻蛀。
簡單的說就是:
當然如果真的這樣大面積的操作 DOM,性能會是一個很大的問題您市,所以 Weex實現了一個虛擬 DOM循榆,組件 DOM 結構就是映射到這個虛擬 DOM 上,weex在這個虛擬 DOM 上實現了一個 diff 算法墨坚,當要更新組件的時候,會通過 diff 尋找到要變更的 DOM 節(jié)點映挂,再把這個修改更新到瀏覽器實際的 DOM 節(jié)點上泽篮,所以實際上不是真的渲染整個 DOM 樹。這個虛擬 DOM 是一個純粹的 JS 數據結構柑船,所以性能會比原生 DOM 快很多帽撑。
3榛斯、Android RenderEngine 將輸入Virtual DOM 轉換成輸出的android原聲控件旱幼;
1、后臺部署時會將weex文件轉換為JSbundle坐桩,大家完全不必擔心這部分的時間逆巍,因為在后臺已經轉換完成及塘;
2、Native 渲染和 JavaScript 引擎之間的邊界放在了 Virtual DOM锐极,兩者通過約定 Virtual DOM 來進行通信笙僚,而不是 template + data 或是別的邊界,確保渲染性能和靈活度的平衡灵再;
3肋层、Weex和native,H5翎迁,RN的對比
1.Weex和H5對比
2.Weex和RN對比
1.目前來說RN也在融合Android和iOS實現栋猖,提供統(tǒng)一的書寫方案,Weex這方面相比之下還是有優(yōu)勢的汪榔,RN稍微慢了一步
2.Weex 有 H5 的解決方案蒲拉,解決了如:分享到外部的問題
3.Weex 目前有效的解決了list比較費內存的情況
4.Weex 的受眾更偏向于前端,因為類Vue的型的書寫方式揍异,足夠簡單全陨。RN的解決方案,提供了很多先進的思路衷掷,誰能勝出辱姨,各家有各家的說法。
3.Weex優(yōu)勢
兼容css和js語法戚嗅,學習成本低雨涛,上手簡單枢舶。三端公用,可直接對H5頁面稍做修改進行使用替久。支持熱更新和降級處理凉泄,基于Vue實現了數據的綁定。
4.Weex劣勢
并不能兼容所有的css蚯根,開發(fā)有一定的局限性后众,設計的時候沒考慮cookie,使用cookie的時候會出現問題颅拦〉儆基礎控件比較少,若想自定義控件需要兩端都實現距帅。
4右锨、Weex開發(fā)中遇到的問題
1.使用本地圖片
<image class = "setBtn" src= 'xcassets:my_setting'/>
- (id<WXImageOperationProtocol>)downloadImageWithURL:(NSString *)url imageFrame:(CGRect)imageFrame userInfo:(NSDictionary *)userInfo completed:(void(^)(UIImage *image, NSError *error, BOOL finished))completedBlock
{
if ([url hasPrefix:@"http://"]) {
url = [@"http:" stringByAppendingString:url];
}
if ([url hasPrefix:@"xcassets:"]) {
UIImage *image = [UIImage imageNamed:[url substringFromIndex:9]];
completedBlock(image, nil, YES);
return [WXXCassetsLoaderOperation new];
}
return (id<WXImageOperationProtocol>)[[SDWebImageManager sharedManager] loadImageWithURL:[NSURL URLWithString:url] options:0 progress:^(NSInteger receivedSize, NSInteger expectedSize, NSURL * _Nullable targetURL) {
} completed:^(UIImage * _Nullable image, NSData * _Nullable data, NSError * _Nullable error, SDImageCacheType cacheType, BOOL finished, NSURL * _Nullable imageURL) {
if (completedBlock) {
completedBlock(image, error, finished);
}
}];
}
2.list中cell的margin無效
<cell class="Mine_fotter">
<div class="Mine_fotter_div">
<image class="fotter_btn_icon" src="xcassets:my_kefu"/>
<text class="fotter_btn_name">我的客服</text>
</div>
</cell>
將cell的最外層嵌套一個div,對div進行margin操作
3.Weex和Native的交互
#pragma mark - 初始化weex配置
- (void)resignWeex{
[WXAppConfiguration setAppGroup:@"AliApp"];
[WXAppConfiguration setAppName:@"Weex_haojie"];
[WXAppConfiguration setAppVersion:@"1.1.0"];
[WXSDKEngine initSDKEnvironment];
[WXSDKEngine registerModule:@"callNative" withClass:[WXCustomEventModule class]];
[WXSDKEngine registerHandler:[WXImgLoaderDefaultImpl new] withProtocol:@protocol(WXImgLoaderProtocol)];
#ifdef DEBUG
[WXLog setLogLevel:WXLogLevelLog];
#endif
}
將WXCustomEventModule注冊為callNative
WX_EXPORT_METHOD(@selector(pushNativeVC::))
/**
跳到原生頁面
@param name 跳轉的原生類名
@param params 參數
*/
- (void)pushNativeVC:(NSString *)name :(id)params{
[self pushToViewController:@"JRSettingController" :params];
}
實現并注冊方法pushNativeVC::
//注冊
const app = weex.requireModule('callNative');
//調用
app.pushNativeVC(methodName);
4.元素的顯示隱藏
<div class="bottomAlert" v-if="isHaojie">
<text class = 'bottomAlertTitle'>{{bottomAlertMsg}}</text>
</div>
因為weex沒有兼容v-show和display:none的屬性,所以要實現元素的顯示隱藏要使用v-if,其值為bool值
5.類選擇器
<div v-for="item in topArray" :class="[loginState?'TopLoginItem':'TopItem']" @click="jump(item.url)">
<image class="topitemIcon" :src="item.icon" />
<text class="topitemTitle">{{item.title}}</text>
</div>
和vue語法不同碌秸,其格式為:class="[loginState?'TopLoginItem':'TopItem']"
6.視圖的生命周期 willAppear绍移,willDisAppear
//js代碼
<div class="body" @viewappear="onViewappear">
</div>
//ios代碼
- (void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
[self updateInstanceState:WeexInstanceAppear];
}
- (void)viewDidDisappear:(BOOL)animated
{
[super viewDidDisappear:animated];
[self updateInstanceState:WeexInstanceDisappear];
}
- (void)updateInstanceState:(WXState)state
{
if (_instance && _instance.state != state) {
_instance.state = state;
if (state == WeexInstanceAppear) {
[[WXSDKManager bridgeMgr] fireEvent:_instance.instanceId ref:WX_SDK_ROOT_REF type:@"viewappear" params:nil domChanges:nil];
}
else if (state == WeexInstanceDisappear) {
[[WXSDKManager bridgeMgr] fireEvent:_instance.instanceId ref:WX_SDK_ROOT_REF type:@"viewdisappear" params:nil domChanges:nil];
}
}
}
5、總結
如果考慮三端讥电,可以嘗試Weex開發(fā)
如果已經有大量實踐Vue蹂窖,也可以嘗試Weex開發(fā)
對渲染UI的流暢度有較高的期望又想能支持熱更新,也可以嘗試Weex開發(fā)