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


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的变量作用域深入理解
Oct 25 Javascript
基于jquery的cookie的用法
Jan 10 Javascript
JQuery入门——用one()方法绑定事件处理函数(仅触发一次)
Feb 05 Javascript
点击A元素触发B元素的事件在IE8下会识别成A元素
Sep 04 Javascript
jQuery实现的数值范围range2dslider选取插件特效多款代码分享
Aug 27 Javascript
jQuery实现下拉框功能实例代码
May 06 Javascript
jQuery简单实现iframe的高度根据页面内容自适应的方法
Aug 01 Javascript
JS设计模式之数据访问对象模式的实例讲解
Sep 30 Javascript
利用jquery和BootStrap实现动态滚动条效果
Dec 03 jQuery
微信小程序实现时间进度条功能
Nov 17 Javascript
JavaScript实现字符串与HTML格式相互转换
Mar 17 Javascript
Node使用koa2实现一个简单JWT鉴权的方法
Jan 26 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
使用CodeIgniter的类库做图片上传
2014/06/12 PHP
php检测apache mod_rewrite模块是否安装的方法
2015/03/14 PHP
php5.4以上版本GBK编码下htmlspecialchars输出为空问题解决方法汇总
2015/04/03 PHP
php用正则判断是否为数字的方法
2016/03/25 PHP
javascript知识点收藏
2007/02/22 Javascript
Track Image Loading效果代码分析
2007/08/13 Javascript
javascript+iframe 实现无刷新载入整页的代码
2010/03/17 Javascript
javascript自执行函数之伪命名空间封装法
2010/12/25 Javascript
Javascript操作URL函数修改版
2013/11/07 Javascript
Js 导出table内容到Excel的简单实例
2013/11/19 Javascript
javascript制作loading动画效果 loading效果
2014/01/14 Javascript
javascript实现图片跟随鼠标移动效果的方法
2015/05/13 Javascript
浅谈Jquery中Ajax异步请求中的async参数的作用
2016/06/06 Javascript
JavaScript导航脚本判断当前导航
2016/07/12 Javascript
JS双击变input框批量修改内容
2016/12/12 Javascript
canvas实现图像布局填充功能
2017/02/06 Javascript
vue-cli项目中怎么使用mock数据
2017/09/27 Javascript
浅谈在vue中用webpack打包之后运行文件的问题以及相关配置方法
2018/02/21 Javascript
JavaScript创建对象方法实例小结
2018/09/03 Javascript
关于RxJS Subject的学习笔记
2018/12/05 Javascript
vue中使用[provide/inject]实现页面reload的方法
2019/09/30 Javascript
Python3编程实现获取阿里云ECS实例及监控的方法
2017/08/18 Python
Pandas实现数据类型转换的一些小技巧汇总
2018/05/07 Python
Python tkinter的grid布局及Text动态显示方法
2018/10/11 Python
Python安装与基本数据类型教程详解
2019/05/29 Python
OpenCV Python实现拼图小游戏
2020/03/23 Python
Python Selenium XPath根据文本内容查找元素的方法
2020/12/07 Python
python 高阶函数简单介绍
2021/02/19 Python
建筑专业自荐信范文
2014/01/05 职场文书
什么是就业协议书
2014/04/17 职场文书
本科毕业生应聘求职信
2014/07/06 职场文书
群众路线领导班子四风对照检查材料
2014/09/27 职场文书
金秋助学感谢信
2015/01/21 职场文书
给下属加薪申请报告
2015/05/15 职场文书
《观察物体》教学反思
2016/02/17 职场文书
vue修饰符.capture和.self的区别
2022/04/22 Vue.js