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


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插件开发 对话框插件开发
Apr 26 Javascript
当json键为数字时的取值方法解析
Nov 15 Javascript
Node.js 异步编程之 Callback介绍(一)
Mar 30 Javascript
基于Jquery实现万圣节快乐特效
Nov 01 Javascript
JavaScript阻止回车提交表单的方法
Dec 30 Javascript
JavaScript中的this机制
Jan 30 Javascript
jQuery animate easing使用方法图文详解
Jun 17 Javascript
IScroll5实现下拉刷新上拉加载的功能实例
Aug 11 Javascript
Vue.js如何实现路由懒加载浅析
Aug 14 Javascript
vue实现在表格里,取每行的id的方法
Mar 09 Javascript
vue watch深度监听对象实现数据联动效果
Aug 16 Javascript
详解vue2.0 资源文件assets和static的区别
Nov 27 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 字符串正则替换函数preg_replace使用说明
2011/07/15 PHP
PHP生成验证码时“图像因其本身有错无法显示”的解决方法
2013/08/07 PHP
PHP实现补齐关闭的HTML标签
2016/03/22 PHP
php获取客户端IP及URL的方法示例
2017/02/03 PHP
让firefox支持IE的一些方法的javascript扩展函数代码
2010/01/02 Javascript
一个级联菜单代码学习及removeClass与addClass的应用
2013/01/24 Javascript
原生Js实现元素渐隐/渐现(原理为修改元素的css透明度)
2013/06/24 Javascript
jQuery实现的向下图文信息滚动效果
2015/05/03 Javascript
javascript实现类似java中getClass()得到对象类名的方法
2015/07/27 Javascript
JavaScript下的时间格式处理函数Date.prototype.format
2016/01/27 Javascript
读Javascript高性能编程重点笔记
2016/12/21 Javascript
基于JavaScript实现窗口拖动效果
2017/01/18 Javascript
ES6使用let命令更简单的实现块级作用域实例分析
2017/03/31 Javascript
Vue中的ref作用详解(实现DOM的联动操作)
2017/08/21 Javascript
JS库之Three.js 简易入门教程(详解之一)
2017/09/13 Javascript
jquery实现的简单轮播图功能【适合新手】
2018/08/17 jQuery
微信小程序使用二次贝塞尔曲线画波浪
2018/12/25 Javascript
kafka调试中遇到Connection to node -1 could not be established. Broker may not be available.
2019/09/17 Javascript
Vue简单实现原理详解
2020/05/07 Javascript
[00:21]DOTA2亚洲邀请赛 Logo演绎
2015/02/07 DOTA
[56:20]LGD vs VP Supermajor 败者组决赛 BO3 第三场 6.10
2018/07/04 DOTA
python 3.6 +pyMysql 操作mysql数据库(实例讲解)
2017/12/20 Python
python3利用Dlib19.7实现人脸68个特征点标定
2018/02/26 Python
Python matplotlib绘图可视化知识点整理(小结)
2018/03/16 Python
解决python3 json数据包含中文的读写问题
2018/05/10 Python
Python实现Linux监控的方法
2019/05/16 Python
详解PyCharm+QTDesigner+PyUIC使用教程
2019/06/13 Python
Python 开发工具PyCharm安装教程图文详解(新手必看)
2020/02/28 Python
使用HTML5中的contentEditable来将多行文本自动增高
2016/03/01 HTML / CSS
h5页面背景图很长要有滚动条滑动效果的实现
2021/01/27 HTML / CSS
Sunglasses Shop英国:欧洲领先的太阳镜在线供应商之一
2018/09/19 全球购物
美国环保妈妈、儿童和婴儿用品购物网站:The Tot
2019/11/24 全球购物
单位单身证明范本
2014/01/11 职场文书
2019年入党思想汇报格式与要求
2019/06/25 职场文书
基于Python和openCV实现图像的全景拼接详细步骤
2021/10/05 Python
MySQL8.0 Undo Tablespace管理详解
2022/06/16 MySQL