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


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 禁止复制网页
Jun 11 Javascript
一个简单的JS时间控件示例代码(JS时分秒时间控件)
Nov 22 Javascript
jQuery中Dom的基本操作小结
Jan 23 Javascript
js读取csv文件并使用json显示出来
Jan 09 Javascript
全面解析Bootstrap中Carousel轮播的使用方法
Jun 13 Javascript
JavaScript随机生成颜色的方法
Oct 15 Javascript
基于SpringMVC+Bootstrap+DataTables实现表格服务端分页、模糊查询
Oct 30 Javascript
js实现简单的计算器功能
Jan 16 Javascript
浅析JavaScript中var that=this
Feb 17 Javascript
vue2.0+vue-router构建一个简单的列表页的示例代码
Feb 13 Javascript
原生JavaScript实现的无缝滚动功能详解
Jan 17 Javascript
vue实现微信浏览器左上角返回按钮拦截功能
Jan 18 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
thinkphp下MySQL数据库读写分离代码剖析
2017/04/18 PHP
JS IE和FF兼容性问题汇总
2009/02/09 Javascript
jquery聚焦文本框与扩展文本框聚焦方法
2012/10/12 Javascript
JQuery与Ajax调用新浪API获取短网址的代码
2014/02/07 Javascript
JQuery中操作Css样式的方法
2014/02/12 Javascript
JavaScript改变CSS样式的方法汇总
2015/05/07 Javascript
JS实现模拟风力的雪花飘落效果
2015/05/13 Javascript
动态加载css方法实现和深入解析
2017/01/18 Javascript
详解vue+vueRouter+webpack的简单实例
2017/06/17 Javascript
JS删除数组里的某个元素方法
2018/02/03 Javascript
浅谈Angularjs中不同类型的双向数据绑定
2018/07/16 Javascript
vue-video-player 通过自定义按钮组件实现全屏切换效果【推荐】
2018/08/29 Javascript
JS实现二维数组元素的排列组合运算简单示例
2019/01/28 Javascript
Vue模板语法中数据绑定的实例代码
2019/05/17 Javascript
JS动态图片的实现方法完整示例
2020/01/13 Javascript
Element InputNumber计数器的使用方法
2020/07/27 Javascript
微信小程序实现可拖动悬浮图标(包括按钮角标的实现)
2020/12/29 Javascript
python实现指定字符串补全空格的方法
2015/04/30 Python
磁盘垃圾文件清理器python代码实现
2020/08/24 Python
Python实现获取前100组勾股数的方法示例
2018/05/04 Python
Python 中字符串拼接的多种方法
2018/07/30 Python
小白入门篇使用Python搭建点击率预估模型
2018/10/12 Python
Python使用while循环花式打印乘法表
2019/01/28 Python
Django ORM 查询管理器源码解析
2019/08/05 Python
加拿大最大的钻石商店:Peoples Jewellers
2018/01/01 全球购物
英国定做窗帘和纺织品面料一站式商店:Dekoria
2018/08/29 全球购物
加拿大在线旅游公司:Flighthub
2019/03/11 全球购物
护士岗位职责
2014/02/16 职场文书
《狼和小羊》教学反思
2014/04/20 职场文书
电话客服工作职责
2014/07/27 职场文书
一年级班主任工作总结2014
2014/11/08 职场文书
2014年银行柜员工作总结
2014/11/12 职场文书
2014年营销工作总结
2014/11/22 职场文书
华山导游词
2015/02/03 职场文书
放假通知格式
2015/04/14 职场文书
浅谈PHP7中的一些小技巧
2021/05/29 PHP