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


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 相关文章推荐
Hutia 的 JS 代码集
Oct 24 Javascript
jQueryUI如何自定义组件实现代码
Nov 14 Javascript
Notify - 基于jquery的消息通知插件
Oct 18 Javascript
查找iframe里元素的方法可传参
Sep 11 Javascript
jQuery满屏焦点图左右滚动特效代码分享
Sep 07 Javascript
jQuery绑定事件的几种实现方式
May 09 Javascript
微信小程序 页面跳转及数据传递详解
Mar 14 Javascript
vue iView 上传组件之手动上传功能
Mar 16 Javascript
详解swipe使用及竖屏页面滚动方法
Jun 28 Javascript
js模拟F11页面全屏显示
Sep 17 Javascript
vue实现pdf文档在线预览功能
Nov 26 Javascript
原生js实现日期选择插件
May 21 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脚本数据库功能详解(下)
2006/10/09 PHP
php使用gzip压缩传输js和css文件的方法
2015/07/29 PHP
Laravel使用Caching缓存数据减轻数据库查询压力的方法
2016/03/15 PHP
详解在PHP的Yii框架中使用行为Behaviors的方法
2016/03/18 PHP
Zend Studio使用技巧两则
2016/04/01 PHP
基于jquery的图片的切换(以数字的形式)
2011/02/14 Javascript
jquery 选择器引擎sizzle浅析
2013/02/06 Javascript
JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)
2013/12/17 Javascript
如何使用PHP+jQuery+MySQL实现异步加载ECharts地图数据(附源码下载)
2016/02/23 Javascript
jQuery实现的省市县三级联动菜单效果完整实例
2016/08/01 Javascript
微信小程序 页面传参实例详解
2016/11/16 Javascript
React Native 搭建开发环境的方法步骤
2017/10/30 Javascript
微信小程序基于本地缓存实现点赞功能的方法
2017/12/18 Javascript
浅谈Vue.js中ref ($refs)用法举例总结
2017/12/19 Javascript
vue一个页面实现音乐播放器的示例
2018/02/06 Javascript
实例详解带参数的 npm script
2019/05/28 Javascript
[03:15]DOTA2-DPC中国联赛1月22日Recap集锦
2021/03/11 DOTA
python基础教程之实现石头剪刀布游戏示例
2014/02/11 Python
详解python中xlrd包的安装与处理Excel表格
2016/12/16 Python
pandas获取groupby分组里最大值所在的行方法
2018/04/20 Python
python 实现调用子文件下的模块方法
2018/12/07 Python
python日志模块logbook使用方法
2019/09/19 Python
线程安全及Python中的GIL原理分析
2019/10/29 Python
在python中创建指定大小的多维数组方式
2019/11/28 Python
Python如何批量生成和调用变量
2020/11/21 Python
Urban Outfitters美国官网:美国生活方式品牌
2016/08/26 全球购物
静心口服夜广告词
2014/03/20 职场文书
科长竞聘演讲稿
2014/05/16 职场文书
道路运输企业安全生产责任书
2014/07/28 职场文书
2014年小学国庆节活动方案
2014/09/16 职场文书
建党伟业观后感
2015/06/01 职场文书
学习党章心得体会2016
2016/01/15 职场文书
诉讼和解协议书
2016/03/23 职场文书
Golang 获取文件md5校验的方法以及效率对比
2021/05/08 Golang
mysql5.7的安装及Navicate长久免费使用的实现过程
2021/11/17 MySQL
JavaScript的Set数据结构详解
2022/02/18 Javascript