微信小程序中多个页面传参通信的学习与实践


Posted in Javascript onMay 05, 2017

前言

微信小程序越来越火,不少公司都在将原生代码转为微信小程序代码。在开发过程中,由于微信小程序wx.navigateBack方法并不支持返回传参,导致一些页面,尤其是从列表页面跳入详情页,用户在详情页改变了状态,返回后无论是否刷新页面,体验都不是很好。在android中,我们一般采用setresult方法来返回参数,或者直接使用rxjava框架或者eventbus框架来解决此类问题。

业务分析

此类需求大概意思是:A页面进入B页面,B页面返回并传值给A。

探索之路

刚开始我想采用一个比较偷懒的方法,利用微信的wx.setStorage缓存在B页面存储,返回A页面,在onshow方法里调用wx.getStorage读取缓存来实现此功能。但是想想解决方式过于投机取巧,也会给日后维护带来大量隐患。
随后我在网上找到获取前一个page的方法,也可以实现此功能,部分代码如下:

var pages = getCurrentPages();
var currPage = pages[pages.length - 1]; //当前页面
var prevPage = pages[pages.length - 2]; //上一个页面

//直接调用上一个页面的setData()方法,把数据存到上一个页面中去
prevPage.setData({
 mdata:1 
})

仔细想了下,代码也不是很安全,因为进B页面的入口可能是多个,这样会导致获取的page出错。

本来是没招了,突然想到微信小程序支持js,然后就找了个轻量级的js库,而且是观察者模式,是我想要的类型。于是,好戏开始了

onfire.js介绍

onfire.js 是一个很简单的事件分发的Javascript库(仅仅 0.9kb),简洁实用。

github地址:https://github.com/hustcc/onfire.js [作者不是我]

本地下载地址:http://xiazai.3water.com/201705/yuanma/onfire.js(3water.com).rar

可以用于:

  • 简单的事件分发;
  • 在 react / vue.js / angular 用于跨组件的轻量级实现;
  • 事件订阅和发布;

实践

整理下思路如下:

  • A页面先订阅一个事件,并定义处理方法。
  • B页面返回时发送消息。
  • A页面卸载时,解除订阅。

A页面代码:

var onfire = require("../utils/onfire.js");
var that;
var eventObj = onfire.on('key', function () {
 //做具体的事
});

Page({
 data: {
 },
 onLoad: function(options) {
 // Do some initialize when page load.
 },
 onReady: function() {
 // Do something when page ready.
 },
 onUnload: function (e) {
 onfire.un('key');
 onfire.un(eventObj2);
 }
})

直接调用onfire.on方法订阅一个名字为key的消息,并且无传参。如果需要传参的话,直接在function里增加参数即可,如var eventObj = onfire.on('key', function (data)...

需要注意:一定要在onUnload里取消订阅key的消息,并取消绑定eventObj

B页面里代码在回调的地方加入

onfire.fire('key');//key为上文中订阅的消息
 //有参数时
 onfire.fire('key','test');

分析库代码

function _bind(eventName, callback, is_one, context) {
 if (typeof eventName !== string_str || typeof callback !== function_str) {
  throw new Error('args: '+string_str+', '+function_str+'');
 }
 if (! hasOwnKey(__onfireEvents, eventName)) {
  __onfireEvents[eventName] = {};
 }
 __onfireEvents[eventName][++__cnt] = [callback, is_one, context];

 return [eventName, __cnt];
 }

从代码中可以看出订阅on方法的时候实际调用_bind方法,该方法,主要是利用一个二维数组来存储订阅的对象。

function _fire_func(eventName, args) {
 if (hasOwnKey(__onfireEvents, eventName)) {
  _each(__onfireEvents[eventName], function(key, item) {
  item[0].apply(item[2], args); //执行订阅时的方法
  if (item[1]) delete __onfireEvents[eventName][key]; // 当类型为只订阅一次时,通知后即移除自己。
  });
 }
 }

fire发送消息方法实质调用_fire_func方法,通过名字key来遍历订阅者,然后通知订阅者。

function un(event) {
 var eventName, key, r = false, type = typeof event;
 if (type === string_str) {
  // 如果存在key值,则移除数组
  if (hasOwnKey(__onfireEvents, event)) {
  delete __onfireEvents[event];
  return true;
  }
  return false;
 }
 else if (type === 'object') {
  eventName = event[0];
  key = event[1];
  //如果找到这个对象则卸载
  if (hasOwnKey(__onfireEvents, eventName) && hasOwnKey(__onfireEvents[eventName], key)) {
  delete __onfireEvents[eventName][key];
  return true;
  }
  //否则返回false
  return false;
 }
 else if (type === function_str) {
  //两层循环来判断是否是方法名
  _each(__onfireEvents, function(key_1, item_1) {
  _each(item_1, function(key_2, item_2) {
   if (item_2[0] === event) {
   delete __onfireEvents[key_1][key_2];
   r = true;
   }
  });
  });
  return r;
 }
 return true;
 }

因为卸载支持按key、对象、方法卸载,所以需要先判断类型,然后按各自规则去解除绑定。

总结

有了这个事件分发库,很多问题游刃而解。好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
Jquery:ajax实现翻页无刷新功能代码
Aug 05 Javascript
js实现的简单radio背景颜色选择器代码
Aug 18 Javascript
分享一个精简的vue.js 图片lazyload插件实例
Mar 13 Javascript
JS简单实现父子窗口传值功能示例【未使用iframe框架】
Sep 20 Javascript
Node.js中DNS模块学习总结
Feb 28 Javascript
详解webpack之图片引入-增强的file-loader:url-loader
Oct 08 Javascript
IE9 elementUI文件上传的问题解决
Oct 17 Javascript
Element的el-tree控件后台数据结构的生成以及方法的抽取
Mar 05 Javascript
JS实现iframe中子父页面跨域通讯的方法分析
Mar 10 Javascript
浅谈JS for循环中使用break和continue的区别
Jul 21 Javascript
three.js 利用uv和ThreeBSP制作一个快递柜功能
Aug 18 Javascript
国庆节到了,利用JS实现一个生成国庆风头像的小工具 详解实现过程
Oct 05 Javascript
微信小程序 开发之全局配置
May 05 #Javascript
jquery实现tab选项卡切换效果(悬停、下方横线动画位移)
May 05 #jQuery
微信小程序 图片上传实例详解
May 05 #Javascript
微信小程序实现登录页云层漂浮的动画效果
May 05 #Javascript
xmlplus组件设计系列之图标(ICON)(1)
May 05 #Javascript
xmlplus组件设计系列之网格(DataGrid)(10)
May 05 #Javascript
移动端web滚动分页的实现方法
May 05 #Javascript
You might like
smarty实例教程
2006/11/19 PHP
MySQL连接数超过限制的解决方法
2011/07/17 PHP
PHP实现模仿socket请求返回页面的方法
2014/11/04 PHP
PHP实现清除wordpress里恶意代码
2015/10/21 PHP
PHP简单检测网址是否能够正常打开的方法
2016/09/04 PHP
Yii2实现ActiveForm ajax提交
2017/05/26 PHP
THREE.JS入门教程(2)着色器-上
2013/01/24 Javascript
js获取对象为null的解决方法
2013/11/21 Javascript
jquery+CSS实现的水平布局多级网页菜单效果
2015/08/24 Javascript
js用类封装pop弹窗组件
2017/10/08 Javascript
详解javascript replace高级用法
2019/02/17 Javascript
解决Layui数据表格显示无数据提示的问题
2019/11/14 Javascript
vue+elementUI动态增加表单项并添加验证的代码详解
2020/12/17 Vue.js
[01:36:57]【09DOTA2第一视角】小骷髅
2014/04/16 DOTA
python中的实例方法、静态方法、类方法、类变量和实例变量浅析
2014/04/26 Python
python结合opencv实现人脸检测与跟踪
2015/06/08 Python
Python利用ansible分发处理任务
2015/08/04 Python
Python的string模块中的Template类字符串模板用法
2016/06/27 Python
pyqt5 获取显示器的分辨率的方法
2019/06/18 Python
python pytest进阶之xunit fixture详解
2019/06/27 Python
Python实现平行坐标图的两种方法小结
2019/07/04 Python
django一对多模型以及如何在前端实现详解
2019/07/24 Python
浅析Python __name__ 是什么
2020/07/07 Python
css3学习心得分享
2013/08/19 HTML / CSS
高性能钓鱼服装:Huk Gear
2019/02/20 全球购物
Harrods英国:世界领先的奢侈品百货商店
2020/09/23 全球购物
沃尔玛旗下墨西哥超市:Bodega Aurrera
2020/11/13 全球购物
中专生自荐信
2013/10/12 职场文书
网管求职信
2014/03/03 职场文书
建议书的格式
2014/05/12 职场文书
文明城市标语
2014/06/16 职场文书
教室标语大全
2014/06/21 职场文书
房屋租赁合同解除协议书
2014/10/11 职场文书
一般基层干部群众路线教育实践活动个人对照检查材料
2014/11/04 职场文书
python疲劳驾驶困倦低头检测功能的实现
2022/04/04 Python
解决springboot druid数据库连接失败后一直重连的方法
2022/04/19 Java/Android