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


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 相关文章推荐
简单的JS多重继承示例
Mar 13 Javascript
腾讯与新浪的通过IP地址获取当前地理位置(省份)的接口
Jul 26 Javascript
关于jQuery的inArray 方法介绍
Oct 08 Javascript
js控制input框只读实现示例
Jan 20 Javascript
javascript实现json页面分页实例代码
Feb 20 Javascript
javascript常用的方法分享
Jul 01 Javascript
jQuery实现的超酷苹果风格图标滑出菜单效果代码
Sep 16 Javascript
详解JavaScript中的Unescape()和String() 函数
Nov 09 Javascript
14 个折磨人的 JavaScript 面试题
Aug 08 Javascript
JS给Array添加是否包含字符串的简单方法
Oct 29 Javascript
详解Vue中数组和对象更改后视图不刷新的问题
Sep 21 Javascript
layui radio点击事件实现input显示和隐藏的例子
Sep 02 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和js如何通过json互相传递数据相关问题探讨
2013/02/26 PHP
php自动识别文件编码并转换为UTF-8的方法
2014/06/12 PHP
CodeIgniter针对数据库的连接、配置及使用方法
2016/03/03 PHP
Highslide.js是一款基于js实现的网页中图片展示插件
2020/03/30 Javascript
jquery $.ajax入门应用一
2008/11/19 Javascript
ExtJs扩展之GroupPropertyGrid代码
2010/03/05 Javascript
ext 列表页面关于多行查询的办法
2010/03/25 Javascript
Javascript 类与静态类的实现(续)
2010/04/02 Javascript
javascript 处理null及null值示例
2014/06/09 Javascript
JavaScript获取一个范围内日期的方法
2015/04/24 Javascript
jquery衣服颜色选取插件效果代码分享
2015/08/28 Javascript
JavaScript实战之菜单特效
2016/08/16 Javascript
jquery获取下拉框中的循环值
2017/02/08 Javascript
vue中如何去掉空格的方法实现
2018/11/09 Javascript
js DOM的事件常见操作实例详解
2019/12/16 Javascript
微信小程序接入腾讯云验证码的方法步骤
2020/01/07 Javascript
Vue封装Axios请求和拦截器的步骤
2020/09/16 Javascript
[01:47]2018年度DOTA2最佳教练-完美盛典
2018/12/16 DOTA
Python cookbook(数据结构与算法)实现查找两个字典相同点的方法
2018/02/18 Python
python如何实现内容写在图片上
2018/03/23 Python
Pytorch之parameters的使用
2019/12/31 Python
使用 Python 在京东上抢口罩的思路详解
2020/02/27 Python
CSS3中的Media Queries学习笔记
2016/05/23 HTML / CSS
CSS3,线性渐变(linear-gradient)的使用总结
2017/01/09 HTML / CSS
HTML5 canvas基本绘图之绘制曲线
2016/06/27 HTML / CSS
美国在线宠物用品商店:Entirely Pets
2017/01/01 全球购物
MAC彩妆澳洲官网:M·A·C AU
2021/01/17 全球购物
介绍一下gcc特性
2012/01/20 面试题
企业内控岗位的职责
2014/02/07 职场文书
军训鉴定表自我鉴定
2014/02/13 职场文书
优秀员工演讲稿
2014/05/19 职场文书
社区综治宣传月活动总结
2014/07/02 职场文书
科学发展观演讲稿
2014/09/11 职场文书
四十九个javascript小知识实用技巧
2021/11/20 Javascript
Redis监控工具RedisInsight安装与使用
2022/03/21 Redis
vue router 动态路由清除方式
2022/05/25 Vue.js