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


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 相关文章推荐
JavaScript中按位“异或”运算符使用介绍
Mar 14 Javascript
jQuery窗口、文档、网页各种高度的精确理解
Jul 02 Javascript
JavaScript的jQuery库中ready方法的学习教程
Aug 14 Javascript
基于jQuery的ajax方法封装
Jul 14 Javascript
JS实现点击网页判断是否安装app并打开否则跳转app store
Nov 18 Javascript
微信小程序授权获取用户详细信息openid的实例详解
Sep 20 Javascript
实现jquery放大镜的两种方法
Feb 22 jQuery
微信小程序实现手势滑动效果
Aug 26 Javascript
Layui之table中的radio在切换分页时无法记住选中状态的解决方法
Sep 02 Javascript
weui上传多图片,压缩,base64编码的示例代码
Jun 22 Javascript
JS猜数字游戏实例讲解
Jun 30 Javascript
jQuery实现日历效果
Sep 11 jQuery
使用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 include加载文件两种方式效率比较
2010/08/08 PHP
php中require和require_once的区别说明
2014/02/27 PHP
PHP安装GeoIP扩展根据IP获取地理位置及计算距离的方法
2016/07/01 PHP
yii2.0整合阿里云oss删除单个文件的方法
2017/09/19 PHP
php微信公众号开发之答题连闯三关
2018/10/20 PHP
详解PHP神奇又有用的Trait
2019/03/25 PHP
Laravel 实现关系模型取出需要的字段
2019/10/10 PHP
CL vs ForZe BO5 第二场 2.13
2021/03/10 DOTA
枚举JavaScript对象的函数
2006/12/22 Javascript
基于OO的动画附加插件,可以实现弹跳、渐隐等动画效果 分享
2013/06/24 Javascript
JS比较两个时间大小的简单示例代码
2013/12/20 Javascript
js二维数组排序的简单示例代码
2014/01/24 Javascript
js实现点击文本框显示日期选择器特效代码分享
2020/05/21 Javascript
javascript中利用柯里化函数实现bind方法
2016/04/29 Javascript
使用CSS+JavaScript或纯js实现半透明遮罩效果的实例分享
2016/05/09 Javascript
总结Javascript中的隐式类型转换
2016/08/24 Javascript
D3.js实现雷达图的方法详解
2016/09/22 Javascript
使用JavaScriptCore实现OC和JS交互详解
2017/03/28 Javascript
使用express+multer实现node中的图片上传功能
2018/02/02 Javascript
基于JavaScript实现单例模式
2019/10/30 Javascript
解决vue 表格table列求和的问题
2019/11/06 Javascript
基于Electron实现桌面应用开发代码实例
2020/07/07 Javascript
python生成九宫格图片
2018/11/19 Python
Python中单线程、多线程和多进程的效率对比实验实例
2019/05/14 Python
python3多线程知识点总结
2019/09/26 Python
matplotlib.pyplot画图并导出保存的实例
2019/12/07 Python
Python编程快速上手——疯狂填词程序实现方法分析
2020/02/29 Python
python实现拼接图片
2020/03/23 Python
HTML5中的新元素介绍
2008/10/17 HTML / CSS
英国高档百货连锁店:John Lewis
2017/11/20 全球购物
聘任书模板
2014/03/29 职场文书
运动员口号
2014/06/09 职场文书
教师职位说明书
2014/07/29 职场文书
上市公司财务总监岗位职责
2015/04/03 职场文书
2016计划生育先进个人事迹材料
2016/02/29 职场文书
英国数字版游戏销量周榜公布 《小缇娜的奇幻之地》登顶
2022/04/03 其他游戏