小程序跨页面数据传递与事件响应

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

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

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

实现思路

  1. 创建一个 Emitter,用于事件处理
  2. 创建一个全局的 Storage
  3. 在第一个页面创建一个 emitter 对象,并添加事件监听,将 emitter 存储到 Storage 中
  4. 在第二个页面从 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 中。

转自:http://www.wxapp-union.com/article-5740-1.html

原文地址:https://www.cnblogs.com/zmdComeOn/p/12053740.html

时间: 2024-10-08 11:22:46

小程序跨页面数据传递与事件响应的相关文章

小程序跨页面传递data数据的三种方法

Q:小程序怎么把页面data里的数据传到另外的页面? 或者小程序怎么吧表单里的数据传到另外的页面?A:1.可以使用url传递数据. 例如在A页面中传递数据,需要注意的是,wx.switchTab中的url不能传参数. wx.navigateTo({url:‘../pageB/pageB?name=raymond&gender=male’}).在B页面中接收数据,通过onLoad的option:Page({onLoad:function(option){console.log(option.nam

unity 登录注册页面数据传递(无数据库)

unity  登录注册页面数据传递(无数据库) 继上一篇随笔.制作unity登录注册页面. 创建一下脚本: 新建脚本"goa"(存储全局变量方便其他脚本的调用): using UnityEngine;using System.Collections; public class goa : MonoBehaviour { //用户名    public const string name = "M_name";    //密码    public const stri

网易云易盾推出面向微信小程序的大数据反作弊产品

近日,国内领先的业务风控服务网易云易盾对外推出面向微信小程序的大数据反作弊产品,源于网易20年的核心业务风控技术与全面稳健的策略模型,有机整合了设备指纹.IP画像.规则引擎等八大能力,可广泛应用电商营销.金融支付.生活服务类小程序场景,帮助企业防范微信小程序端的黑灰产作弊侵害. 易盾安全调查显示,小程序已成为企业业务风险环节新缺口 易盾安全经过调查发现,相比App,大部分互联网开发者还没有足够的能力利用小程序的特性建立起有效的风控策略."羊毛党"通过自己养号或着批量购买的大量微信号,就

微信小程序开发本地数据缓存教程

微信小程序开发过程中,本地数据缓存是必不可少的一部分.而且本地数据缓存的用途还挺多的,下面木鱼小铺(https://www.muyu007.cn)就和大家分享一下微信小程序开发本地数据缓存教程,希望对大家有所帮助! 第一步:读写本地数据缓存 微信小程序为了方便开发者缓存数据提供了读写本地数据缓存接口,读本地数据缓存采用的是wx.getStorage/wx.getStorageSync接口,写本地数据缓存的是wx.setStorage/wx.setStorageSync接口.其中以Sync结尾的是

微信小程序授权页面

微信小程序授权页面,效果图如下 app.js  中的 onLaunch或onShow中加如下代码,如果没授权跳转到授权页面 // 获取用户信息 wx.getSetting({ success: res => { if (res.authSetting['scope.userInfo']) { // 已经授权,可以直接调用 getUserInfo 获取头像昵称,不会弹框 wx.getUserInfo({ success: res => { // 可以将 res 发送给后台解码出 unionId

微信小程序开发之数据存储 参数传递 数据缓存

微信小程序开发内测一个月.数据传递的方式很少.经常遇到页面销毁后回传参数的问题,小程序中并没有类似Android的startActivityForResult的方法,也没有类似广播这样的通讯方式,更没有类似eventbus的轮子可用. 现在已知传递参数的方法只找到三种,先总结下.由于正处于内测阶段,文档也不是很稳定,经常修改,目前尚没有人造轮子. 先上GIF: 1.APP.js 我把常用且不会更改的参数放在APP.js的data里面了.在各个page中都可以拿到var app = getApp(

微信小程序之页面拦截器

场景 小程序有52个页面,其中13个页面无需任何身份,另外39个页面需要系统角色.对于这39个页面,如果微信用户没有系统角色,则跳转到登录页.是否有系统角色信息需要通过异步请求来获取. 需求分析&实现 对需求进行抽象,其实要的就是一个过滤器,对小程序页面的访问进行过滤,符合条件的通过,不符合条件进行其他处理. 使用过php的laravel框架的童鞋,肯定一下子就联想到了laravel框架的http中间件:HTTP 中间件提供一个方便的机制来过滤进入应用程序的 HTTP 请求,例如,Laravel

浅谈微信小程序实现页面数据显示

前段时间公司需要一个小程序去实现某项简单的功能,本来作为一个后台人员,只需要完成数据接口和文档部分就可以了: 后来对这小程序好奇再加上文档蛮完整的,然后抽了好几天时间去研究了一下,不多说了.. 1.首先来看简单的目录结构: 2.下面是app.json 需要注意的地方: 3.接着是index页面的数据 4.最后是index页面效果 好了,简单的第一步已经完成了.

微信小程序的页面跳转

小程序页面的跳转: 先创建页面toolbar,并在app.json里面pages写上路径 "pages":[    "pages/index/index",    "pages/logs/logs",    "pages/toolbar/toolbar"  ], 然后写在页面中添加按钮,然后添加事件, <button type="primary" bindtap="start"&g