Weex開發(fā):頁面間通信方式

Weex超多大坑,最好別用

白菜普及

Weex 基于當(dāng)代先進(jìn)的 Web 開發(fā)技術(shù),使用同一套代碼來構(gòu)建 Android竹揍、iOS 和 Web 應(yīng)用材失。
Weex 的結(jié)構(gòu)是解耦的痕鳍,渲染引擎與語法層是分開的,也不依賴任何特定的前端框架龙巨,目前主要支持 Vue.js 和 Rax 這兩個前端框架笼呆。Weex 的另一個主要目標(biāo)是跟進(jìn)當(dāng)代先進(jìn)的 Web 開發(fā)和原生開發(fā)的技術(shù),使生產(chǎn)力和性能共存旨别。在開發(fā) Weex 頁面就像開發(fā)普通網(wǎng)頁一樣诗赌;在渲染 Weex 頁面時和渲染原生頁面一樣。

Weex與Native頁面之間的通信主要是用module和globalEvent來實(shí)現(xiàn)秸弛,其中g(shù)lobalEvent可以為通過vue交互來與weex進(jìn)行通信

一. globalEvent:

globalEvent 用于監(jiān)聽持久性事件铭若,全局事件是需要額外 APIs 處理的次要 API洪碳。通過 addEventListener 注冊事件監(jiān)聽,當(dāng)你不再需要的時候奥喻,也可以通過 removeEventListener 取消事件監(jiān)聽偶宫。

Native端

let testDic = ["key" : "native主動發(fā)起廣播至weex"]  
 weexInstance.fireGlobalEvent("NativeGlobalEvent", params: testDic)

Vue.js


const globalEvent = weex.requireModule('globalEvent')
export default {
  methods: {
    ......省略N多代碼
    addGlobalObserver() {
      globalEvent.addEventListener("NativeGlobalEvent", function (e) {
        modal.alert({
          message: e.key,
        });
      })
    },
    removeGlobalObserver() {
      globalEvent.removeEventListener("NativeGlobalEvent")
    }
  }
}

坑:多次調(diào)用addEventListener方法后,無法覆蓋回調(diào)(函數(shù))环鲤,會觸發(fā)多次回調(diào)的執(zhí)行纯趋。
exp: Vue.js多次調(diào)用addEventListener方法(比如5次),當(dāng)Native的Weex實(shí)例發(fā)起fireGlobalEvent時冷离,會直接執(zhí)行5次函數(shù)體的 內(nèi)的代碼塊吵冒;再此基礎(chǔ)上手動調(diào)用3次,在native端再進(jìn)行一次fireGlobalEvent操作西剥,則會累積執(zhí)行8次函數(shù)體內(nèi)的代碼塊痹栖!但是如果調(diào)用removeEventListener,則會把這“八份回調(diào)”全部清除瞭空。
所以實(shí)現(xiàn)通知時候需要額外處理相關(guān)的代碼邏輯

二.注冊Module和callback回調(diào)

Native端

  • 創(chuàng)建一個遵循WXModuleProtocol協(xié)議的 NSObject 類揪阿,并通過宏WX_EXPORT_METHOD將類中定義的方法暴露給Weex,而在native中執(zhí)行完操作后咆畏,可以在設(shè)計接口處添加回調(diào)南捂,通過block與對應(yīng)Weex頁面進(jìn)行通信(比如傳必要的參數(shù)給Weex頁面),其中回調(diào)block有兩種旧找,WXModuleCallback 和 WXModuleKeepAliveCallback

void (^WXModuleCallback)(id result):回調(diào)僅執(zhí)行一次后釋放
void (^WXModuleKeepAliveCallback)(id result, BOOL keepAlive):回調(diào)一直存在溺健,根據(jù)keepAlive的值來決定回調(diào)是僅執(zhí)行一次還是一直保留。注意:回傳的result數(shù)據(jù)可以是任意類型(NSDictionary, NSString, NSArray, Int, Float, Bool)钮蛛,因此要提前與編寫Vue的童鞋約定好對應(yīng)的格式

- (void)showInfoFromWeexKeepAlive:(nullable NSDictionary *)infos keepAliveCallback:(nullable WXModuleKeepAliveCallback)callback {
    
    UIAlertController *alert = [[UIAlertController alloc] init];
    alert.title = @"Native Alert";
    alert.message = infos[@"message"];
    UIAlertAction *action0 = [UIAlertAction actionWithTitle:@"got it" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        
        callback(@{@"backInfo":@"confirm btn click"},true);
    }];
    
    UIAlertAction *action1 = [UIAlertAction actionWithTitle:@"cancle" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
        
        callback(@{@"backInfo":@"cancle btn click"},false);
    }];
    
    [alert addAction:action0];
    [alert addAction:action1];
    
    [UIApplication.sharedApplication.keyWindow.rootViewController presentViewController:alert animated:YES completion:nil];
    
   <!- 模擬block keepAlive場景 ->
    callback(@{@"backInfo":@"this is the first callback and keep block alive"},true);
}
  • 然后在Appdelegate方法中初始化完Weex環(huán)境后鞭缭,通過調(diào)用 WXSDKEngine 中的 registerModule:withClass方法來注冊自己的Module,以便Weex能夠識別并使用Native定義的Module
WXSDKEngine.initSDKEnvironment()    
WXSDKEngine.registerModule("YFTest", with: TestWXModule.classForCoder())

vue.js端

  • 通過requireModule引入native定義的module魏颓,且需同名
  • 調(diào)用module中開放的API執(zhí)行相關(guān)操作
const nativeEvent = weex.requireModule('YFTest')
export default {
  methods: {

    ......省略N多代碼
    sendParamToNativeKeepAlive(event) {
      nativeEvent.showInfoFromWeexKeepAlive({"message":"show message from weex"}, function(ret) {

        var str = "";
        str = ret.backInfo;
        modal.confirm({
          message: "weex alert\n" + str,
          okTitle: 'i know'
        })
      });
    }
  }
};

坑:回調(diào)函數(shù)可能釋放也可能一直存在岭辣,需要對不同的應(yīng)用場景進(jìn)行區(qū)分

三、在寫vue.js頁面的發(fā)現(xiàn)在native上很多CSS的樣式不支持

  • 簡寫均不支持甸饱,如:margin: 15px 15px 30px 30px;
  • 百分比不支持易结,如:width: 80%
  • 不能使用嵌套的CSS,布局上只支持flex
  • native上不存在全局樣式柜候,使用了預(yù)處理器也是不行(查了資料,web是可以有全局樣式)
  • ue.js頁面使用內(nèi)置modal模塊的toast時躏精,無法屏蔽多次點(diǎn)擊操作渣刷,需要特殊處理
  • weexView無法使用自動布局,渲染完成的weex頁面的frame與weexInstance的frame保持一致

四矗烛、頁面之間的跳轉(zhuǎn)

  • native -> weex:weex頁面需要一個控制器作為容器, 此時就是native間的跳轉(zhuǎn)
  • weex -> weex: 使用weex內(nèi)置的navigator模塊辅柴,weex之間傳遞數(shù)據(jù)需要用內(nèi)置模塊storage
  • weex -> native: 需要通過module形式通過發(fā)送事件到native來實(shí)現(xiàn)跳轉(zhuǎn)(參照module的使用)

附:降級方案參考文章

餓了么
飛豬
根據(jù)接口配置箩溃,接口同時給native提供js文件和h5鏈接

  • 由后臺決定Native使用何種方式加載(Weex | Web)
  • 如果后臺指定使用weex,如果渲染失斅掂帧(包括降級和其他一些會導(dǎo)致渲染失敗的原因)則直接移除用來渲染weex頁面的view涣旨,并改用webView來實(shí)現(xiàn)
    坑:如果使用webView來實(shí)現(xiàn),頁面之間的通信也就變成了hybrid方式股冗,而不是前面討論的weex-native之間的module方式
weexInstance.onFailed = { [weak self] (view) in
     //渲染出錯霹陡,包括降級,需要在這里切換至web展示
}
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末止状,一起剝皮案震驚了整個濱河市烹棉,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌怯疤,老刑警劉巖浆洗,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異集峦,居然都是意外死亡伏社,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進(jìn)店門塔淤,熙熙樓的掌柜王于貴愁眉苦臉地迎上來摘昌,“玉大人,你說我怎么就攤上這事凯沪〉谘妫” “怎么了?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵妨马,是天一觀的道長挺举。 經(jīng)常有香客問我,道長烘跺,這世上最難降的妖魔是什么湘纵? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮滤淳,結(jié)果婚禮上梧喷,老公的妹妹穿的比我還像新娘。我一直安慰自己脖咐,他們只是感情好铺敌,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著屁擅,像睡著了一般偿凭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上派歌,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天弯囊,我揣著相機(jī)與錄音痰哨,去河邊找鬼。 笑死匾嘱,一個胖子當(dāng)著我的面吹牛斤斧,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播霎烙,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼撬讽,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了吼过?” 一聲冷哼從身側(cè)響起锐秦,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎盗忱,沒想到半個月后酱床,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡趟佃,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年扇谣,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片闲昭。...
    茶點(diǎn)故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡罐寨,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出序矩,到底是詐尸還是另有隱情鸯绿,我是刑警寧澤,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布簸淀,位于F島的核電站瓶蝴,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏租幕。R本人自食惡果不足惜舷手,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望劲绪。 院中可真熱鬧男窟,春花似錦、人聲如沸贾富。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽颤枪。三九已至姥芥,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間汇鞭,已是汗流浹背凉唐。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留霍骄,地道東北人台囱。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像读整,于是被迫代替她去往敵國和親簿训。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容