微信小程序跨页面数据传递事件响应实现过程解析


Posted in Javascript onDecember 19, 2019

这篇文章主要介绍了微信小程序跨页面数据传递事件响应实现过程解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下

在实际工作中有很多场景需要在第二个页面中将用户操作之后的将数据回传到上一页面。接下来将我的方案分享给小伙伴。 本次示例采用 uni-app 框架和 weui 样式库 实现思路 创建一个 Emitter,用于事件处理 创建一个 ...

在实际工作中有很多场景需要在第二个页面中将用户操作之后的将数据回传到上一页面。接下来将我的方案分享给小伙伴。

本次示例采用 uni-app 框架和 weui 样式库

实现思路

  • 创建一个 Emitter,用于事件处理
  • 创建一个全局的 Storage
  • 在第一个页面创建一个 emitter 对象,并添加事件监听,将 emitter 存储到 Storage 中
  • 在第二个页面从 Storage 中取出 emitter 对象, 并触发事件,将数据传递到第一个页面中做处理

创建 Emitter

function isFunc(fn) {
 return typeof fn === 'function';
}

export default class Emitter {
 constructor() {
 this._store = {};
 }

 /**
 * 事件监听
 * @param {String} event 事件名
 * @param {Function} listener 事件回调函数
 */
 on(event, listener) {
 const listeners = this._store[event] || (this._store[event] = []);

 listeners.push(listener);
 }

 /**
 * 取消事件监听
 * @param {String} event 事件名
 * @param {Function} listener 事件回调函数
 */
 off(event, listener) {
 const listeners = this._store[event] || (this._store[event] = []);

 listeners.splice(listeners.findIndex(item => item === listener), 1);
 }

 /**
 * 事件监听 仅监听一次
 * @param {String} event 事件名
 * @param {Function} listener 事件回调函数
 */
 once(event, listener) {
 const proxyListener = (data) => {
  isFunc(listener) && listener.call(null, data);

  this.off(event, proxyListener);
 }

 this.on(event, proxyListener);
 }

 /**
 * 触发事件
 * @param {String} 事件名
 * @param {Object} 传给事件回调函数的参数
 */
 emit(event, data) {
 const listeners = this._store[event] || (this._store[event] = []);

 for (const listener of listeners) {
  isFunc(listener) && listener.call(null, data);
 }
 }
}

创建 Storage

export class Storage {
 constructor() {
 this._store = {};
 }

 add(key, val) {
 this._store[key] = val;
 }
 
 get(key) {
 return this._store[key];
 }
 
 remove(key) {
 delete this._store[key];
 }
 
 clear() {
 this._store = {};
 }
}

export default new Storage();

第一个页面中的处理

<template>
 <div class="page">
 <div class="weui-cells__title">选择城市</div>
 <div class="weui-cells weui-cells_after-title">
  <navigator :url="`../select/select?id=${cityId}`" class="weui-cell weui-cell_access" hover-class="weui-cell_active">
  <div class="weui-cell__hd weui-label">所在城市</div>
  <div class="weui-cell__bd" :style="{color: cityName || '#999'}">{{ cityName || '请选择' }}</div>
  <div class="weui-cell__ft weui-cell__ft_in-access"></div>
  </navigator>
 </div>
 </div>
</template>

<script>
import Emitter from '../../utils/emitter';
import storage from '../../utils/storage';

export default {
 data() {
 return {
  cityId: '',
  cityName: '',
 }
 },
 onLoad() {
 const emitter = new Emitter();

 // 将emitter存到storage中
 storage.add('indexEmitter', emitter);

 // 添加事件监听
 emitter.on('onSelect', this.handleSelect);
 },
 methods: {
 // 事件处理
 handleSelect(data) {
  this.cityId = data.id;
  this.cityName = data.text;
 }
 }
}
</script>

第二个页面中的处理

<template>
 <div class="page">
 <div class="weui-cells__title">城市列表</div>
 <div class="weui-cells weui-cells_after-title">
  <radio-group @change="handleChange">
  <label class="weui-cell weui-check__label" v-for="item in list" :key="item.id">
   <radio class="weui-check" :value="item.id" :checked="`${item.id}` === selectedId" />
   <div class="weui-cell__bd">{{ item.text }}</div>
   <div v-if="`${item.id}` === selectedId" class="weui-cell__ft weui-cell__ft_in-radio">
   <icon class="weui-icon-radio" type="success_no_circle" size="16" />
   </div>
  </label>
  </radio-group>
 </div>
 </div>
</template>

<script>
import storage from '../../utils/storage';

export default {
 data() {
 return {
  list: [
  { id: 0, text: '北京' },
  { id: 1, text: '上海' },
  { id: 2, text: '广州' },
  { id: 3, text: '深圳' },
  { id: 4, text: '杭州' },
  ],
  selectedId: ''
 }
 },
 onLoad({ id }) {
 this.selectedId = id;
 
 // 取出 emitter
 this.emitter = storage.get('indexEmitter');
 },
 methods: {
 handleChange(e) {
  this.selectedId = e.detail.value;

  const item = this.list.find(({ id }) => `${id}` === e.detail.value);

  // 触发事件并传递数据
  this.emitter.emit('onSelect', { ...item });
 }
 }
}
</script>

传送门

github

总结

之所以将Storage定义成全局的,是为了保证第一个页面放到Storage中和第二个页面从 Storage 中取出的emitter是同一个实例,如此第一个页面才能正确监听到第二个页面触发的事件。也可以使用 vuex,将 emitter 放到 state 中。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JavaScript判断窗口是否最小化的代码(跨浏览器)
Aug 01 Javascript
常见浏览器多长时间会提示“脚本运行时间过长”总结
Apr 29 Javascript
jquery选择器需要注意的问题
Nov 26 Javascript
js实现数字每三位加逗号的方法
Feb 05 Javascript
JavaScript添加随滚动条滚动窗体的方法
Feb 23 Javascript
jQuery实现两列等高并自适应高度
Dec 22 Javascript
Bootstrap实现提示框和弹出框效果
Jan 11 Javascript
jQuery中map函数的两种方式
Apr 07 jQuery
Bootstrap实现基于carousel.js框架的轮播图效果
May 02 Javascript
angularjs使用gulp-uglify压缩后执行报错的解决方法
Mar 07 Javascript
vue中轮训器的使用
Jan 27 Javascript
JavaScript如何实现监听键盘输入和鼠标监点击
Jul 20 Javascript
js通过循环多张图片实现动画效果
Dec 19 #Javascript
JS实现水平移动与垂直移动动画
Dec 19 #Javascript
5分钟快速看懂ES6中的反射与代理
Dec 19 #Javascript
d3.js实现图形拖拽
Dec 19 #Javascript
d3.js实现图形缩放平移
Dec 19 #Javascript
微信小程序批量上传图片到七牛(推荐)
Dec 19 #Javascript
echarts实现折线图的拖拽效果
Dec 19 #Javascript
You might like
两个强悍的php 图像处理类1
2009/06/15 PHP
php Smarty初体验二 获取配置信息
2011/08/08 PHP
解析Win7 XAMPP apache无法启动的问题
2013/06/26 PHP
PHP strip_tags()去除HTML、XML以及PHP的标签介绍
2014/02/18 PHP
php通过字符串调用函数示例
2014/03/02 PHP
PHP二分查找算法示例【递归与非递归方法】
2016/09/29 PHP
PHP 图片处理
2020/09/16 PHP
JavaScript设置首页和收藏页面的小例子
2013/11/11 Javascript
javascript实现带下拉子菜单的导航菜单效果
2015/05/14 Javascript
js获取浏览器高度 窗口高度 元素尺寸 偏移属性的方法
2016/11/21 Javascript
AngularJS 在同一个界面启动多个ng-app应用模块详解
2016/12/20 Javascript
微信小程序 实现点击添加移除class
2017/06/12 Javascript
LayUI表格批量删除方法
2018/08/15 Javascript
详解NodeJs项目 CentOs linux服务器线上部署
2019/09/16 NodeJs
[43:41]VP vs RNG 2019国际邀请赛淘汰赛 败者组 BO3 第二场 8.21.mp4
2020/07/19 DOTA
python encode和decode的妙用
2009/09/02 Python
使用Python脚本来控制Windows Azure的简单教程
2015/04/16 Python
python实现逆波兰计算表达式实例详解
2015/05/06 Python
详细解析Python中的变量的数据类型
2015/05/13 Python
Python计算斗牛游戏概率算法实例分析
2017/09/26 Python
python使用Matplotlib绘制分段函数
2018/09/25 Python
详解Python中正则匹配TAB及空格的小技巧
2019/07/26 Python
python 怎样将dataframe中的字符串日期转化为日期的方法
2019/09/26 Python
python os.path.isfile 的使用误区详解
2019/11/29 Python
python3中pip3安装出错,找不到SSL的解决方式
2019/12/12 Python
意大利高端时尚买手店:Stefania Mode
2018/03/01 全球购物
LivingSocial英国:英国本地优惠
2019/02/22 全球购物
英国顶级足球鞋的领先零售商:Lovell Soccer
2019/08/27 全球购物
个人综合鉴定材料
2014/05/23 职场文书
专科应届毕业生求职信
2014/06/04 职场文书
明星邀请函
2015/02/02 职场文书
新娘父亲婚礼致辞
2015/07/27 职场文书
HR必备:超全面的薪酬待遇管理方案!
2019/07/12 职场文书
Pandas||过滤缺失数据||pd.dropna()函数的用法说明
2021/05/14 Python
vue中 this.$set的使用详解
2021/11/17 Vue.js
Python+Tkinter制作专属图形化界面
2022/04/01 Python