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(); } })