本文來自尚妝Android團隊路飛
發表於尚妝github博客,歡迎訂閱!vue接入weex已有幾個月,各方面都已慢慢完善。最近遇到一個點,先記錄一下。後續會花時間整理一系列weex相關的文章。但願早點完成。git
如今有不少頁面須要在返回的時候刷新,好比從購物車跳轉到詳情頁加購,再到購物車,這時候應該刷新頁面;若是從訂單列表頁點擊付款跳轉後進行支付後,返回的時候刷新數據。github
首先想到的是weex已經提供的綁定到根元素的viewappear 和 viewdisappear事件。使用方法是綁定到根元素上,自定義過component的同窗在這裏應該不難猜到它是基於fireEvent實現的
。web
public void onResume() { if (wxInstance != null) { wxInstance.onActivityResume(); } }
public void onPause() { if (wxInstance != null) { wxInstance.onActivityPause(); } }
- (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]; } } } -(void)viewDidAppear:(BOOL)animated { [super viewDidAppear:animated]; [self updateInstanceState:WeexInstanceAppear]; } - (void)viewDidDisappear:(BOOL)animated { [super viewDidDisappear:animated]; [self updateInstanceState:WeexInstanceDisappear]; }
到此,viewappear 和 viewdisappear事件是能夠知足以上返回刷新的需求的,只要在vue 裏判斷:當觸發viewappear事件時,若是不是第一次觸發,就當作是返回,根據需求,作刷新請求就能夠了。
json
由此想到,若是不只須要這樣的事件,還想給當前頁面,從native發其餘事件到js,也不基於界面元素,那麼該如何辦呢?weex
首先想到的是weex提供的globalEvent,三端均可以發送事件,接收的時候只要註冊一下就行了。app
var globalEvent = weex.requireModule('globalEvent'); globalEvent.addEventListener("geolocation", function (e) { console.log("get geolocation") });
不過,通過實驗會發現,它是全局的,意思是,一個activity/viewcontroller包含多個weex時,只要註冊了這個事件,那麼就都會收到這個事件。那麼一旦咱們發送的事件名稱出現同樣時,就埋了坑,可能出現事件錯亂。dom
這裏的解決方案可能會想到規範event name來達到杜絕名稱同樣的狀況,不過這更可能是一種治標不治本的辦法。函數
因而就有了本文要介紹的方案,讓頁面傳的事件只有本身頁面的js處理。ui
講道理,這個功能,要是在weex sdk裏實現再好不過了。
說來簡單,該方案基於globalEvent,攜帶instanceId,weex裏經過比對instanceId,只有一致的狀況下才進行處理。
在渲染weex的fragment/activity的onresume裏調用:
resumed:成員變量,默認false
if (resumed) { Map<String,Object> params = new HashMap<>(); params.put("id", wxInstance.getInstanceId()); wxInstance.fireGlobalEventCallback("resume", params); } resumed = true;
在自定義module裏增長接口:
@JSMethod(uiThread = true) public void getInstanceId(final JSCallback callback) { if (null != callback) { JSONObject jsonObject = new JSONObject(); jsonObject.put("id", mWXSDKInstance.getInstanceId()); callback.invoke(jsonObject); } }
在渲染weex的viewController裏調用:
resumed:成員變量,默認false
-(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; if (self.resumed) { [_instance fireGlobalEvent:@"resume" params:@{@"id": _instance.instanceId}]; } self.resumed = true; }
在自定義module裏增長接口:
-(void)getInstanceId:(WXModuleCallback)callback{ callback(@{@"id": weexInstance.instanceId}); }
weex工程裏,封裝一個函數,其中shopBase
是自定義的module
const shopBase = weex.requireModule('shopBase'); export default { methods: { /** * config: * { * event, name of event * callback * } */ addEventListener(event, callback) { if(weex.config.env.platform.toLowerCase() !== 'web') { shopBase.getInstanceId((data) => { const globalEvent = weex.requireModule('globalEvent'); const id = data.id; globalEvent.addEventListener(event, function (e) { if(e.id === id) { callback(e); } }); }) } }, }, };
在須要的頁面調用便可,用法同globalEvent:
addEventListener('resume', function (e) { shopModal.toast({ message: e.id }); });