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


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代码实例
Jun 15 Javascript
JavaScript 未结束的字符串常量常见解决方法
Jan 24 Javascript
基于jquery实现的文字淡入淡出效果
Nov 14 Javascript
javascript实现简单的Map示例介绍
Dec 23 Javascript
超级简单实现JavaScript MVC 样式框架
Mar 24 Javascript
javascript验证邮件地址和MX记录的方法
Jun 16 Javascript
认识Knockout及如何使用Knockout绑定上下文
Dec 25 Javascript
令按钮悬浮在(手机)页面底部的实现方法
May 02 Javascript
灵活使用console让js调试更简单的方法步骤
Apr 23 Javascript
vue父组件触发事件改变子组件的值的方法实例详解
May 07 Javascript
vue-cli3 配置开发与测试环境详解
May 17 Javascript
js实现星星海特效的示例
Sep 28 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提交后跳转
2013/06/23 PHP
Laravel框架表单验证详解
2014/09/04 PHP
thinkphp框架page类与bootstrap分页(美化)
2017/06/25 PHP
静态的动态续篇之来点XML
2006/12/23 Javascript
nicejforms——美化表单不用愁
2007/02/20 Javascript
escape、encodeURI 和 encodeURIComponent 的区别
2009/03/02 Javascript
使用Post提交时须将空格转换成加号的解释
2013/01/14 Javascript
Jquery响应回车键直接提交表单操作代码
2014/07/25 Javascript
详解js私有作用域中创建特权方法
2016/01/25 Javascript
Bootstrap时间选择器datetimepicker和daterangepicker使用实例解析
2016/09/17 Javascript
Bootstrop实现多级下拉菜单功能
2016/11/24 Javascript
Bootstrap 下拉多选框插件Bootstrap Multiselect
2017/01/22 Javascript
js中小数向上取整数,向下取整数,四舍五入取整数的实现(必看篇)
2017/02/13 Javascript
原生js实现瀑布流布局
2017/03/08 Javascript
详解angular中通过$location获取路径(参数)的写法
2017/03/21 Javascript
记录一篇关于redux-saga的基本使用过程
2018/08/18 Javascript
vue设计一个倒计时秒杀的组件详解
2019/04/06 Javascript
关于vue状态过渡transition不起作用的原因解决
2019/04/09 Javascript
VUE 单页面使用 echart 窗口变化时的用法
2020/07/30 Javascript
js实现点击选项置顶动画效果
2020/08/25 Javascript
Vue router安装及使用方法解析
2020/12/02 Vue.js
[01:03:22]LGD vs OG 2018国际邀请赛淘汰赛BO3 第一场 8.25
2018/08/29 DOTA
[59:53]DOTA2-DPC中国联赛 正赛 VG vs Elephant BO3 第二场 3月6日
2021/03/11 DOTA
用Python的Django框架完成视频处理任务的教程
2015/04/02 Python
Python批量创建迅雷任务及创建多个文件
2016/02/13 Python
Python简单检测文本类型的2种方法【基于文件头及cchardet库】
2016/09/18 Python
python xlsxwriter库生成图表的应用示例
2018/03/16 Python
python使用turtle绘制国际象棋棋盘
2019/05/23 Python
python 实现手机自动拨打电话的方法(通话压力测试)
2019/08/08 Python
简单了解Python write writelines区别
2020/02/27 Python
美国在线宠物用品商店:Entirely Pets
2017/01/01 全球购物
如何用Java判断一个文件或目录是否存在
2012/11/19 面试题
学生自我鉴定模板
2013/12/30 职场文书
党的群众路线教育实践活动制度建设计划
2014/11/03 职场文书
南京南京观后感
2015/06/02 职场文书
2016应届毕业生实习心得体会
2015/10/09 职场文书