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


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 相关文章推荐
拖动布局之保存布局页面cookies篇
Oct 29 Javascript
js 动态文字滚动的例子
Jan 17 Javascript
在jQuery ajax中按钮button和submit的区别分析
Oct 07 Javascript
扩展jQuery对象时如何扩展成员变量具体怎么实现
Apr 25 Javascript
基于Jquery制作图片文字排版预览效果附源码下载
Nov 18 Javascript
改变checkbox默认选中状态及取值的实现代码
May 26 Javascript
AngularJS国际化详解及示例代码
Aug 18 Javascript
原生JS下拉加载插件分享
Dec 26 Javascript
bootstrap daterangepicker汉化以及扩展功能
Jun 15 Javascript
微信小程序实现下拉刷新和轮播图效果
Nov 21 Javascript
ES2020让代码更优美的运算符 (?.) (??)
Jan 04 Javascript
javascript实现拼图游戏
Jan 29 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
《Re:从零开始的异世界生活 冰结之绊》
2020/04/09 日漫
php中echo()和print()、require()和include()等易混淆函数的区别
2012/02/22 PHP
php实现在线通讯录功能(附源码)
2016/05/13 PHP
PHP中overload与override的区别
2017/02/13 PHP
ThinkPHP5.1框架数据库链接和增删改查操作示例
2019/08/03 PHP
js下写一个事件队列操作函数
2010/07/19 Javascript
文本框根据输入内容自适应高度的代码
2011/10/24 Javascript
jQuery代码性能优化的10种方法
2016/06/21 Javascript
JavaScript字符串对象(string)基本用法示例
2017/01/18 Javascript
jQuery 添加样式属性的优先级别方法(推荐)
2017/06/08 jQuery
Angularjs单选框相关的示例代码
2017/08/17 Javascript
使用sessionStorage解决vuex在页面刷新后数据被清除的问题
2018/04/13 Javascript
详解操作虚拟dom模拟react视图渲染
2018/07/25 Javascript
Vue项目报错:Uncaught SyntaxError: Unexpected token
2018/11/10 Javascript
vue-cli配置全局sass、less变量的方法
2019/06/06 Javascript
小程序实现分类页
2019/07/12 Javascript
Node.js path模块,获取文件后缀名操作
2020/11/07 Javascript
ant design的table组件实现全选功能以及自定义分页
2020/11/17 Javascript
[01:41]DOTA2 2015国际邀请赛中国区预选赛第三日战报
2015/05/28 DOTA
[02:10]DOTA2 TI10勇士令状玩法及不朽Ⅰ展示:焕新世界,如你所期
2020/05/29 DOTA
Python爬虫 scrapy框架爬取某招聘网存入mongodb解析
2019/07/31 Python
Python 分发包中添加额外文件的方法
2019/08/16 Python
基于Python实现ComicReaper漫画自动爬取脚本过程解析
2019/11/11 Python
python sitk.show()与imageJ结合使用常见的问题
2020/04/20 Python
HTML5 Web Workers之网站也能多线程的实现
2013/04/24 HTML / CSS
毕业生毕业总结的自我评价范文
2013/11/02 职场文书
《守株待兔》教学反思
2014/03/01 职场文书
道德大讲堂实施方案
2014/05/14 职场文书
电气工程及其自动化专业求职信
2014/06/23 职场文书
2014年结对帮扶工作总结
2014/12/17 职场文书
公司职员入党自传书
2015/06/26 职场文书
MySQL 如何分析查询性能
2021/05/12 MySQL
用python开发一款操作MySQL的小工具
2021/05/12 Python
Java用自带的Image IO给图片添加水印
2021/06/15 Java/Android
Node实现搜索框进行模糊查询
2021/06/28 Javascript
python接口测试返回数据为字典取值方式
2022/02/12 Python