小程序数据通信方法大全(推荐)


Posted in Javascript onApril 15, 2019

本文论述的是子或孙向父传递数据的情况,自下而上

相信大家平时在小程序开发中肯定遇到过页面或者组件之间的数据通信问题,那小程序数据通信都有哪些方式呢?如何选择合适的通信方式呢?这就是本文要讨论的重点。

关系划分

在讨论都有哪些数据通信方式之前,我们先来定义一下,小程序页面、组件之间都有哪些关系。我总结了一下,大概分为以下3类:

  1. 父子关系
  2. 兄弟关系
  3. 爷孙关系

不同的关系里面,不同角色之间有可能是页面,也有可能是组件,接下来我们就一个个来揭示如何进行数据通信。

父子关系

父子关系一般主要就是两种情况:

父为页面,子为组件 父为组件,子为组件

这种关系可能是频率出现最高的了,毕竟大部分小程序页面都是以小而美为主,可能没有分的太细,碰到这种情况,我们可以通过在父页面监听子组件触发的事件来完成数据通信。

方法一

<!-- 当自定义组件触发“myevent”事件时,调用“onMyEvent”方法 -->
<component-tag-name bindmyevent="onMyEvent" />

<!-- 在自定义组件中 -->
<button bindtap="onTap">点击这个按钮将触发“myevent”事件</button>
Component({
 methods: {
  onTap() {
   const myEventDetail = {} // detail对象,提供给事件监听函数
   const myEventOption = {} // 触发事件的选项
   this.triggerEvent('myevent', myEventDetail, myEventOption)
  }
 }
})

小程序数据通信方法大全(推荐) 

兄弟关系

兄弟关系同样分为两种情况:

  1. 兄弟间都是页面
  2. 兄弟间都是组件

兄弟间都是页面

这种关系指的就是,同层次间的页面,简单理解其实就是页面之间的跳转,那从页面A跳到页面B,页面B如何修改页面A的数据呢?

方法二

页面生命周期里面都有 onShow``onHide 方法,通过 localStorage 或者 globalData 作为数据中转,进入到不同页面时,在前一个页面 onShow 里面取出数据,在后一个页面 onShow 里面存储数据,具体做法如下:

<!--app.js-->
App({
  globalData: { count: 0 },
});

<!--页面A-->
onShow(){
  let countValue = wx.getStorageSync('count');
  
  <!--globalData的方式-->
  let countValue = getApp().globalData.count;
  <!---->
  
  if(countValue){
    this.setData({
      count:countValue
    })
  }
  
  <!--globalData的方式 清除数据-->
  getApp().globalData.count = null
  <!---->
}
onHide(){
  wx.removeStorageSync('count') 
}

<!--页面B-->
onShow(){
  <!--globalData的方式-->
  getApp().globalData.count = 1
  <!---->
  
  wx.setStorageSync('count',1);
}

小程序数据通信方法大全(推荐) 

爷孙关系

爷孙关系算是数据通信中最复杂的了,因为不是直系传递,若是通过 方法一 来监听,那就需要通过多级传递事件了,如果节点比较深,可想而知代码是得多难理解且难以维护。

我们可以通过全局创建一个事件总栈 EventBus ,利用这个 EventBus 来订阅发布事件,也就是我们经常使用的 发布订阅模式 ,那在小程序里面如何实现呢?

方法三

<!--第一步:实现一个事件总栈类-->
class EventBus {
  constructor() {
    this.bus = {};
  }
  // on 订阅
  on(type, fun) {
    if (typeof fun !== 'function') {
      console.error('fun is not a function');
      return;
    }
    (this.bus[type] = this.bus[type] || []).push(fun);
  }
  // emit 触发
  emit(type, ...param) {
    let cache = this.bus[type];
    if (!cache) return;
    for (let event of cache) {
      event.call(this, ...param);
    }
  }
  // off 释放
  off(type, fun) {
    let events = this.bus[type];
    if (!events) return;
    let i = 0,
      n = events.length;
    for (i; i < n; i++) {
      let event = events[i];
      if (fun === event) {
        events.splice(i, 1);
        break;
      }
    }
  }
}
module.exports = EventBus;

<!--第二步:在app.js文件中引入-->
import EventBus from './common/event-bus/index.js';
App({
  eventBus: new EventBus(),
});

<!--第三步:在父页面或者父组件中监听某个事件-->
onLoad: function(options) {
  app.eventBus.on('add-count', this.addCount);
}
onUnload: function(options) {
  app.eventBus.off('add-count', this.addCount);
}


<!--第四步:在子组件里面触发事件-->
methods: {
  addCount() {
    app.eventBus.emit('add-count');
  }
}

小程序数据通信方法大全(推荐)

除此之外,还有一种方式,我们可以在每个页面 onLoad 周期里面将该页面的 pageModel 对象缓存起来,之后在孙辈组件里面拿到祖孙的页面对象,从而触发祖孙页面对象对应的方法。

<!--第一步:实现一个pageModel,用来缓存页面对象-->
class PageModel {
  constructor() {
    this.pageCache = {};
  }

  add(page) {
    let pagePath = this._getPageModelPath(page);
    this.pageCache[pagePath] = page;
  }

  get(path) {
    return this.pageCache[path];
  }

  delete(page) {
    delete this.pageCache[this._getPageModelPath(page)];
  }
  <!--这一段代码是关键,存储的是__route__属性-->
  _getPageModelPath(page) {
    return page.__route__;
  }
}

export default PageModel ;

<!--第二步:app.js中引入-->
import PageModel from './common/page-model/index.js';

App({
  pageModel: new PageModel(),
});

<!--第三步:页面onLoad周期里缓存页面-->
onLoad: function(options) {
  app.pageModel.add(this);
}

<!--第四步:子孙获取祖辈方法-->
methods: {
  addCount() {
    app.pageModel.get('pages/communicate/index').addCount();
  }
}

小程序数据通信方法大全(推荐)

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

Javascript 相关文章推荐
JavaScript 开发中规范性的一点感想
Jun 23 Javascript
网站页面自动跳转实现方法PHP、JSP(下)
Aug 01 Javascript
JavaScript高级程序设计 阅读笔记(十七) js事件
Aug 14 Javascript
Javascript基础教程之关键字和保留字汇总
Jan 18 Javascript
javascript实现密码强度显示
Mar 18 Javascript
jQuery实现仿Google首页拖动效果的方法
May 04 Javascript
通过npm引用的vue组件使用详解
Mar 02 Javascript
jQuery导航条固定定位效果实例代码
May 26 jQuery
Angular.js组件之input mask对input输入进行格式化详解
Jul 10 Javascript
javascript流程控制语句集合
Sep 18 Javascript
vue watch普通监听和深度监听实例详解(数组和对象)
Aug 16 Javascript
详解微信图片防盗链“此图片来自微信公众平台 未经允许不得引用”的解决方案
Apr 04 Javascript
前端面试知识点目录一览
Apr 15 #Javascript
详解vuex持久化插件解决浏览器刷新数据消失问题
Apr 15 #Javascript
vue-cli项目使用mock数据的方法(借助express)
Apr 15 #Javascript
说说Vuex的getters属性的具体用法
Apr 15 #Javascript
vue 中Virtual Dom被创建的方法
Apr 15 #Javascript
详解jQuery中的getAll()和cleanData()
Apr 15 #jQuery
详解javascript对数组和json数组的操作
Apr 15 #Javascript
You might like
论建造顺序的重要性
2020/03/04 星际争霸
php一次性删除前台checkbox多选内容的方法
2013/09/22 PHP
PHP将字符分解为多个字符串的方法
2014/11/22 PHP
关于php微信订阅号开发之token验证后自动发送消息给订阅号但是没有消息返回的问题
2015/12/21 PHP
thinkphp 字母函数详解T/I/N/D/M/A/R/U
2017/04/03 PHP
php模仿qq空间或朋友圈发布动态、评论动态、回复评论、删除动态或评论的功能(中)
2017/06/11 PHP
深入理解JavaScript 闭包究竟是什么
2013/04/12 Javascript
jquery将一个表单序列化为一个对象的方法
2013/12/02 Javascript
js与jQuery 获取父窗、子窗的iframe
2013/12/20 Javascript
JQuery 控制内容长度超出规定长度显示省略号
2014/05/23 Javascript
IE6 hack for js 集锦
2014/09/23 Javascript
黑帽seo劫持程序,js劫持搜索引擎代码
2015/09/15 Javascript
关于javascript中dataset的问题小结
2015/11/16 Javascript
有关JavaScript中call()和apply() 的一些理解
2016/05/20 Javascript
vue.js指令v-model使用方法
2017/03/20 Javascript
Vue2.0基于vue-cli+webpack父子组件通信(实例讲解)
2017/09/14 Javascript
vue使用axios时关于this的指向问题详解
2017/12/22 Javascript
Vue2.0子同级组件之间数据交互方法
2018/02/28 Javascript
[07:06]2018DOTA2国际邀请赛寻真——卫冕冠军Team Liquid
2018/08/10 DOTA
python 数据的清理行为实例详解
2017/07/12 Python
python机器人行走步数问题的解决
2018/01/29 Python
python实现祝福弹窗效果
2019/04/07 Python
解决Django生产环境无法加载静态文件问题的解决
2019/04/23 Python
Django 大文件下载实现过程解析
2019/08/01 Python
python 中值滤波,椒盐去噪,图片增强实例
2019/12/18 Python
python字典setdefault方法和get方法使用实例
2019/12/25 Python
pytorch 中的重要模块化接口nn.Module的使用
2020/04/02 Python
使用pygame实现垃圾分类小游戏功能(已获校级二等奖)
2020/07/23 Python
CSS实现半透明边框与多重边框的场景分析
2019/11/13 HTML / CSS
div或img图片高度随宽度自适应的方法
2020/02/06 HTML / CSS
英国Office鞋店德国网站:在线购买鞋子、靴子和运动鞋
2018/12/19 全球购物
瑞士网球商店:Tennis-Point
2020/03/12 全球购物
Linux文件系统类型
2012/09/16 面试题
党课学习思想汇报
2014/01/02 职场文书
篮球赛闭幕式主持词
2015/07/03 职场文书
《家庭教育》读后感3篇
2019/12/18 职场文书