本文来自尚妆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 }); });