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


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 相关文章推荐
js 字符串转化成数字的代码
Jun 29 Javascript
jquery移除button的inline onclick事件(已测试及兼容浏览器)
Jan 25 Javascript
JS数组排序技巧汇总(冒泡、sort、快速、希尔等排序)
Nov 24 Javascript
快速学习AngularJs HTTP响应拦截器
Dec 31 Javascript
浅析AMD CMD CommonJS规范--javascript模块化加载学习心得总结
Mar 16 Javascript
JavaScript判断浏览器及其版本信息
Jan 20 Javascript
canvas绘制的直线动画
Jan 23 Javascript
详解jQuery中ajax.load()方法
Jan 25 Javascript
微信小程序 图片加载(本地,网路)实例详解
Mar 10 Javascript
ECMAscript 变量作用域总结概括
Aug 18 Javascript
浅谈HTTP 缓存的那些事儿
Oct 17 Javascript
JavaScript中this的学习笔记及用法整理
Feb 17 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
Windows下利用Gvim写PHP产生中文乱码问题解决方法
2011/04/20 PHP
PHP+Ajax实现上传文件进度条动态显示进度功能
2018/06/04 PHP
PDO::getAvailableDrivers讲解
2019/01/28 PHP
关于juqery radio写法的兼容性问题(新老版本jquery)
2010/06/14 Javascript
新鲜出炉的js tips提示效果
2011/04/03 Javascript
常用一些Javascript判断函数
2012/08/14 Javascript
JQuery+CSS提示框实现思路及代码(纯手工打造)
2013/05/07 Javascript
js导出格式化的excel 实例方法
2013/07/17 Javascript
js替换字符串的所有示例代码
2013/07/23 Javascript
jquery下div 的resize事件示例代码
2014/03/09 Javascript
JavaScript实现带标题的图片轮播特效
2015/05/20 Javascript
Javascript实现通过选择周数显示开始日和结束日的实现代码
2016/05/30 Javascript
详解jquery easyui之datagrid使用参考
2016/12/05 Javascript
MUI 上拉刷新/下拉加载功能实例代码
2017/04/13 Javascript
深究AngularJS——ng-checked(回写:带真实案例代码)
2017/06/13 Javascript
使用原生js封装的ajax实例(兼容jsonp)
2017/10/12 Javascript
仿淘宝JSsearch搜索下拉深度用法
2018/01/15 Javascript
浅谈在vue中用webpack打包之后运行文件的问题以及相关配置方法
2018/02/21 Javascript
Angular6中使用Swiper的方法示例
2018/07/09 Javascript
vue中的计算属性实例详解
2018/09/19 Javascript
使用Python进行新浪微博的mid和url互相转换实例(10进制和62进制互算)
2014/04/25 Python
python使用turtle库绘制时钟
2020/03/25 Python
基于python 取余问题(%)详解
2020/06/03 Python
关于tf.matmul() 和tf.multiply() 的区别说明
2020/06/18 Python
应届毕业生应聘自荐信
2013/12/07 职场文书
校本教研工作方案
2014/01/14 职场文书
公休请假条
2014/04/11 职场文书
鼓舞士气的口号
2014/06/16 职场文书
会计求职自荐信
2014/06/20 职场文书
班级元旦晚会开幕词
2015/01/29 职场文书
国王的演讲观后感
2015/06/03 职场文书
三好学生竞选稿
2015/11/21 职场文书
Nest.js参数校验和自定义返回数据格式详解
2021/03/29 Javascript
Python re.sub 反向引用的实现
2021/07/07 Python
MySQL配置主从服务器(一主多从)
2021/08/07 MySQL
win server2012 r2服务器共享文件夹如何设置
2022/06/21 Servers