首页 » 漏洞 » 「前端」weex页面传参

「前端」weex页面传参

 

本文来自尚妆前端团队南洋

发表于尚妆 github博客 ,欢迎订阅!

前言

我司在weex上的应用是保证三端统一,为了延续web开发体验,统一在三端的跳转都采用url的形式,即采用<a>组件,或者自定义的openUrl方法进行跳转。

假如现在点击 B按钮 跳转到 /b.html 页面,在vue文件中统一书写 openUrl('/b.html') 。H5中就是简单的调用 window.location.href = /b.html ,在native中会打开一个视图,然后去下载跟 /b.html 对应的 b.min.js js文件,进行原生视图渲染。页面与js文件的映射关系以及如何维护可以翻阅之前的 文章 查看App的跳转规则的weex支持方案设计。

统一采用url跳转的方式进行页面跳转,为了传参方便,我们也统一采用在url后拼接参数的形式进行页面间传参。

正向传参

不管是weex(native)还是weex(H5)都是通过页面的url进行跳转。

假设案例:

x.com/a.html 跳转到 x.com/b.html?age=12

1)weex(native) > weex(native) 实例化时从url中取得参数并传入到实例中

weex文档中写到

每个 Weex 页面都有被创建、被销毁两个必经阶段,同时在 Weex 页面运行过程中,native 有机会主动向 Weex 页面发送消息。

Native 有机会在创建一个 Weex 页面的时候,传入一份外部数据,JS 框架也有机会借此机会为相同的 JS bundle 配合不同的 data 生成不同的页面内容。

由上可知native在渲染一个weex页面的时候有机会往这个weex页面传入一个Object类型的数据,数据能通过 weex.config 取得。

在我司的设计中,native首先会截取跳转的url,然后截取下参数,再把参数传入到weex实例中去。这样我们就能通过 weex.config.age 进行数据的获取,从而渲染不同的页面内容。

[_instance renderWithURL:[NSURL URLWithString:mstrURL] options:[self SHWeexOptionsWithH5URL:mstrH5URL withURL:mstrURL] data:nil];

2)weex(web)> weex(web)在weex-vue-render层面从url读取参数,写入weex.config

native实现这上述讲到的方式进行数据传递,那么web端也要以相同的方式 weex.config.age 这种方式去取得页面中的参数age。

本司web端的weex依赖文件是通过webpack打包的方式,所以在require weex-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) 同理

对于3、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页面正向的传参方式。

反向传参

1)weexA(native) > weexB(native),weexB页面选择完毕返回weexA页面, weexB(native) > weexA(native)

「前端」weex页面传参

「前端」weex页面传参

在提交订单页面我们可以选择优惠券,进入到优惠券使用页面,首先会进行正向传参,因为选择优惠券页面会使用提交订单页的订单数据。

然后在选择优惠券页面选择任意优惠券会回到提交订单页,这时需要携带优惠券数据回去,我们称这个为反向传参。

查看官网我们本可以使用 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会在上一个页面出现时,去缓存中取得之前存入的数据和事件名,再调用官方提供的实例api fireGlobalEventCallback ,调用对应的事件,并传数据。

当native中执行了 fireGlobalEventCallback 这个方法,上一页的事件监听函数就会取得数据。

至此就完成了native中数据的反向传递。

2)weexA(web) > weexB(web), weexB(web) > weexA(web)

反向传递参数在weex的web端就更加好处理了,AB页面都是通过连接后面拼接参数的形式进行传递参数,那么反向传参跟正向传参还是可以按照之前的逻辑进行。

在设计api时特意在回调中会对是否web环境做了判断,因为H5和native在反向传参的行为完全不同,所以判断逻辑会在业务中进行,更方便大家在写业务时进行不同情况不同处理。

fireGlobalEvent('getConpon', {     id: '3323',   }, function () {   if (web) {       openUrl('/a.html?id=' + '3323');   } else {     navigator.pop();   } })

原文链接:「前端」weex页面传参,转载请注明来源!

0