如何让微信小程序页面之间的通信不再变困难


Posted in Javascript onJune 03, 2019

一个开始

小程序开发者总会碰到各种页面之间的通信问题,实现方式也五花八门,比如...

场景还原

首先这是一个电商小程序。

有这样一个需求:

  • 首页某个地方要展示购物车商品数量。
  • 当我在其他页面加购了商品,首页数量刷新。

实现方式

方式一:onShow直接请求接口

Page({
 onShow() {
 // ...一些逻辑
 
 // 后端请求新的购物车数量
 this.requestCartNum();
 }
})

不足: 每次onShow都要请求接口,浪费资源。

方式二:globalData存储购物车数量,onShow中做刷新

// 主页.js
Page({
 onShow() {
  // 在globalData获取到购物车数据
  let num = globalData.cartNum;
  if (num !== this.data.cartNum) {
   this.setData({
    cartNum: num,
   });
  }
 }
});

// 加购页.js
Page({
 // 加购后改变globalData的值
 cartAdd(num) {
  globalData.cartNum = globalData.cartNum + num;
 }
})

方式三:加购后获取首页实例,调用首页方法

// 首页.js
Page({
 onCartAdd(num) {
  this.setData({
   cartNum: this.data.cartNum + num,
  });
 },
});

// 加购页.js
Page({
 onCartAdd(num) {
  // 加购后获取到首页的实例,调用首页onCartAdd方法
  let pages = getCurrentPages();
  let curPage = pages[0];
  curPage.onCartAdd(num);
 }
})

不足:不确定能不能准确拿到首页的实例,如果换做其他页面就很难复用

方法四:事件订阅与发布

// 首页.js
Page({
 onLoad() {
  // 首页监听事件
  this.$bus.on('cart_add', (num) => {
   this.setData({
    cartNum: this.data.cartNum + num,
   })
  })
 }
})

// 加购页.js

Page({
 // 加购成功后触发cart_add事件
 onCartAdd(num) {
  this.$bus.emit('cart_add', num);
 }
})

此方法用事件系统,订阅发布模式去做的处理。

以上几种方法中最优解决方案是方法四,利用事件的订阅与发布,逻辑清晰兼容性好。但是都不可避免的不足是:每一个需要动态显示购物数量的页面都需要添加相同的逻辑代码。

状态管理方案

单页应用中最常用的就是组件之间的通信,由此诞生了不同的状态存储方案: react用redux, vue用vuex。他们的思路都是类似的。都有一个核心 store 存储着一切要管理的状态。

那么,其他框架可以,小程序也可以。以redux为例,实现一套简单的状态管理方案。

wxdux的实现

使用前提:有redux基础

wxdux 类似与redux,以action来描述触发的行为,reducer来描述state的变化。

1. 小程序入口中注册

注册store并添加到globalData中去

import {createStore} from './wxdux/index';
import reducer from './reducer';

const store = createStore(reducer);

App({
 globalData: {
  store,
 },
});

2. reducer实现

写法与redux类似,功能也类似。

const userReducer = (state = {}, action) => {
 // ...
}

const postReducer = (state = [], action) => {
 // ...
};

const reducers = {
 user: userReducer,
 posts: postReducer,
};

export default reducers;

3. 页面中使用wxdux

connect方法会将小程序页面实例与wxdux连接起来,必须提供$useState方法,该方法接收state,返回该页面所需要的state

import {connect} from './wxdux/index';

Page(connect({
 data: {
  sex: '男',
 },
 onLoad() {
  // ...
 },
 $useState(state) {
  return {
   name: state.name,
  },
 },
}))

4. wxml中使用name

<view>{{name}}</view>

5. 触发store更新

使用dispatch方法,该方法接收一个对象作为参数,该对象必须包含type字段表示action的类型,wxdux会根据此action更新state并且刷新所有使用name的视图

import {dispatch} from './wxdux/index';

Page(connect({
 // 某点击事件触发,更新姓名为“张三”
 onClick() {
  const updateName = {
   type: 'update_name',
   name: '张三'
  };
  dispatch(updateName);
 }
}))

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
jQuery的实现原理的模拟代码 -4 重要的扩展函数 extend
Aug 03 Javascript
JavaScript高级程序设计 阅读笔记(二十) js错误处理
Aug 14 Javascript
js switch case default 的用法示例介绍
Oct 23 Javascript
JavaScript实现的in_array函数
Aug 27 Javascript
Javascript基础知识(二)事件
Sep 29 Javascript
AngularJS表单编辑提交功能实例
Feb 13 Javascript
JavaScript 实现的 zip 压缩和解压缩工具包Zip.js使用详解
Dec 14 Javascript
总结Javascript中的隐式类型转换
Aug 24 Javascript
利用JQuery实现datatables插件的增加和删除行功能
Jan 06 Javascript
js 博客内容进度插件详解
Feb 19 Javascript
Vue-cropper 图片裁剪的基本原理及思路讲解
Apr 17 Javascript
JavaScript 实现下雪特效的示例代码
Sep 09 Javascript
使用VueRouter的addRoutes方法实现动态添加用户的权限路由
Jun 03 #Javascript
使用watch在微信小程序中实现全局状态共享
Jun 03 #Javascript
深入理解JS异步编程-Promise
Jun 03 #Javascript
模块化react-router配置方法详解
Jun 03 #Javascript
react 组件传值的三种方法
Jun 03 #Javascript
angular使用md5,CryptoJS des加密的方法
Jun 03 #Javascript
Node.js 的 GC 机制详解
Jun 03 #Javascript
You might like
PHP与MySQL开发的8个技巧小结
2010/12/17 PHP
使用php发送有附件的电子邮件-(PHPMailer使用的实例分析)
2013/04/26 PHP
PHP 实现页面静态化的几种方法
2017/07/23 PHP
php设计模式之原型模式分析【星际争霸游戏案例】
2020/03/23 PHP
popdiv
2006/07/14 Javascript
javascript jq 弹出层实例
2013/08/25 Javascript
JS实现一个列表中包含上移下移删除等功能
2014/09/24 Javascript
微信小程序  wx.request合法域名配置详解
2016/11/23 Javascript
完美解决jQuery 鼠标快速滑过后,会执行多次滑出的问题
2016/12/08 Javascript
基于VUE选择上传图片并页面显示(图片可删除)
2017/05/25 Javascript
angularJs中跳转到指定的锚点实例($anchorScroll)
2018/08/31 Javascript
javascript获取select值的方法完整实例
2019/06/20 Javascript
js生成1到100的随机数最简单的实现方法
2020/02/07 Javascript
解决elementUI 切换tab后 el_table 固定列下方多了一条线问题
2020/07/19 Javascript
关于Node.js中频繁修改代码重启服务器的问题
2020/10/15 Javascript
[01:07:19]DOTA2-DPC中国联赛 正赛 CDEC vs XG BO3 第一场 1月19日
2021/03/11 DOTA
在Python中使用元类的教程
2015/04/28 Python
约瑟夫问题的Python和C++求解方法
2015/08/20 Python
Python实现完整的事务操作示例
2017/06/20 Python
python Web开发你要理解的WSGI &amp; uwsgi详解
2018/08/01 Python
Pycharm pyuic5实现将ui文件转为py文件,让UI界面成功显示
2020/04/08 Python
PageFactory设计模式基于python实现
2020/04/14 Python
罗兰·穆雷官网:Roland Mouret
2018/09/28 全球购物
美国社交购物市场:MassGenie
2019/02/18 全球购物
Linux的主要特性
2014/10/06 面试题
业务经理岗位职责
2013/11/11 职场文书
同学聚会老师邀请函
2014/01/28 职场文书
法人授权委托书格式
2014/04/08 职场文书
授权委托书格式
2014/07/31 职场文书
2015年五四青年节活动总结
2015/02/10 职场文书
奖励通知
2015/04/22 职场文书
2015年档案室工作总结
2015/05/23 职场文书
2016春季运动会通讯稿
2015/07/18 职场文书
2015年车间管理工作总结
2015/07/23 职场文书
创业计划书之寿司
2019/07/19 职场文书
mysql的数据压缩性能对比详情
2021/11/07 MySQL