19年目標:消滅英語!我新開了一個公衆號記錄一個程序員學英語的歷程html
有提高英語訴求的小夥伴能夠關注公衆號:csenglish 程序員學英語,天天花10分鐘交做業,跟我一塊兒學英語吧vue
我司在weex上的應用是保證三端統一,爲了延續web開發體驗,統一在三端的跳轉都採用url的形式,即採用<a>組件,或者自定義的openUrl方法進行跳轉。android
假如如今點擊B按鈕
跳轉到/b.html
頁面,在vue文件中統一書寫openUrl('/b.html')
。H5中就是簡單的調用window.location.href = /b.html
,在native中會打開一個視圖,而後去下載跟/b.html
對應的b.min.js
js文件,進行原生視圖渲染。頁面與js文件的映射關係以及如何維護能夠翻閱以前的文章查看App的跳轉規則的weex支持方案設計。webpack
統一採用url跳轉的方式進行頁面跳轉,爲了傳參方便,咱們也統一採用在url後拼接參數的形式進行頁面間傳參。ios
無論是weex(native)仍是weex(H5)都是經過頁面的url進行跳轉。git
假設案例:程序員
x.com/a.html
跳轉到x.com/b.html?age=12
。github
weex文檔中寫到web
每一個 Weex 頁面都有被建立、被銷燬兩個必經階段,同時在 Weex 頁面運行過程當中,native 有機會主動向 Weex 頁面發送消息。
Native 有機會在建立一個 Weex 頁面的時候,傳入一份外部數據,JS 框架也有機會藉此機會爲相同的 JS bundle 配合不一樣的 data 生成不一樣的頁面內容。
由上可知native在渲染一個weex頁面的時候有機會往這個weex頁面傳入一個Object類型的數據,數據能經過weex.config
取得。apache
在我司的設計中,native首先會截取跳轉的url,而後截取下參數,再把參數傳入到weex實例中去。這樣咱們就能經過weex.config.age
進行數據的獲取,從而渲染不一樣的頁面內容。
[_instance renderWithURL:[NSURL URLWithString:mstrURL] options:[self SHWeexOptionsWithH5URL:mstrH5URL withURL:mstrURL] data:nil];
native實現這上述講到的方式進行數據傳遞,那麼web端也要以相同的方式weex.config.age
這種方式去取得頁面中的參數age。
本司web端的weex依賴文件是經過webpack打包的方式,因此在requireweex-vue-render
依賴後,獲取當前url的參數,再存進weex.config
對象就行了。
require('weex-vue-render') // hack 將頁面url的參數寫入到weex.config中 // app已經有這樣的方法,h5本身實現 let urlParamObj = {}; try { urlParamObj = utils.parseUrl(window.location.search.slice(1), '&', "=", {maxKeys: 0}); } catch (error) { console.log('--------------weex.js parseUrl---------------------'); console.log(error); console.log('------------------------------------'); } for (let key in urlParamObj) { window.weex.config[key] = encodeURIComponent(urlParamObj[key]); }
3)native > weex(native) 同理
4)native > weex(web) 同理
對於三、4兩種狀況,native跳轉weex,無論是跳到weex(native)仍是跳轉到weex(web),都是使用url的形式進行跳轉。例:x.com/b.html?age=12
。上面也講到了在weex頁面native和web如如何將參數寫入weex.config對象中去的。要取得參數,統一在vue中編寫weex.config.age
便能取得傳遞進來的age參數。
至此咱們統一了三端(ios、android、H5)從A頁面到B頁面正向的傳參方式。
在提交訂單頁面咱們能夠選擇優惠券,進入到優惠券使用頁面,首先會進行正向傳參,由於選擇優惠券頁面會使用提交訂單頁的訂單數據。
而後在選擇優惠券頁面選擇任意優惠券會回到提交訂單頁,這時須要攜帶優惠券數據回去,咱們稱這個爲反向傳參。
查看官網咱們本可使用BroadcastChannel這個api去作實例間的數據傳遞,可是在vue的JS Framework
中還不支持這個特性,因此咱們暫時使用的是globalEvent這個實例級別的api去代替應用級別的數據傳遞。
咱們首先在公司內部集成的module中增長了fireGlobalEvent
方法,在選擇優惠券頁面調用這個方法。
fireGlobalEvent('getConpon', { id: '3323', }, function () { if (web) { } else { navigator.pop() } })
這個方法首先註冊了getCoupon
事件,而後傳遞了數據對象
{ id: '3323' }
最後註冊了一個回調,當前頁面會執行這個回調,回退上一頁。
而在上一頁(提交訂單頁),註冊了一個事件監聽,當這個事件名被觸發了,就接收來自這個事件的數據。
const globalEvent = weex.requireModule('globalEvent'); globalEvent.addEventListener('getCoupon', function (e) { console.log("get getCoupon") });
這是業務邏輯中的實現,咱們再來看看native爲了達到返回上一頁並傳參效果作了什麼處理(android爲例)。
public void fireGlobalEvent(String name, String data, final JSCallback callback) { SHStorageManager.putToCache(SHWeexConstants.WEEX, SHWeexConstants.NAME, name); SHStorageManager.putToCache(SHWeexConstants.WEEX, SHWeexConstants.DATA, data); if (null != callback) { callback.invoke(new JSONObject()); } }
當在業務中調用fireGlobalEvent
方法時,native會把傳入的事件名和data存入緩存。而後執行業務中定義的回調函數,而回調中會有navigator.pop()
方法,意味着退出當前weex實例進入到上一個頁面。
public void onResume() { if (wxInstance != null) { wxInstance.onActivityResume(); String data = SHStorageManager.get(SHWeexConstants.WEEX, SHWeexConstants.DATA, ""); if (!TextUtils.isEmpty(data)) { String name = SHStorageManager.get(SHWeexConstants.WEEX, SHWeexConstants.NAME, ""); try { JSONObject jsonObj = JSONObject.parseObject(data); Map<String, Object> params = new HashMap<>(); for (Map.Entry<String, Object> entry : jsonObj.entrySet()) { params.put(entry.getKey(), entry.getValue()); } wxInstance.fireGlobalEventCallback(name, params); } catch (Exception e) { SHWeexLog.e(e); } finally { SHStorageManager.removeFromCache(SHWeexConstants.WEEX, SHWeexConstants.DATA); SHStorageManager.removeFromCache(SHWeexConstants.WEEX, SHWeexConstants.NAME); } } } }
而後native會在上一個頁面出現時,去緩存中取得以前存入的數據和事件名,再調用官方提供的實例apifireGlobalEventCallback,調用對應的事件,並傳數據。
當native中執行了fireGlobalEventCallback
這個方法,上一頁的事件監聽函數就會取得數據。
至此就完成了native中數據的反向傳遞。
反向傳遞參數在weex的web端就更加好處理了,AB頁面都是經過鏈接後面拼接參數的形式進行傳遞參數,那麼反向傳參跟正向傳參仍是能夠按照以前的邏輯進行。
在設計api時特地在回調中會對是否web環境作了判斷,由於H5和native在反向傳參的行爲徹底不一樣,因此判斷邏輯會在業務中進行,更方便你們在寫業務時進行不一樣狀況不一樣處理。
fireGlobalEvent('getConpon', { id: '3323', }, function () { if (web) { openUrl('/a.html?id=' + '3323'); } else { navigator.pop(); } })