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


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下的keyCode键码值表
Apr 10 Javascript
根据出生日期自动取得星座的js代码
Jul 20 Javascript
js如何设置在iframe框架中指定div不显示
Dec 04 Javascript
JQuery实现的购物车功能(可以减少或者添加商品并自动计算价格)
Jan 13 Javascript
js实现跟随鼠标移动且带关闭功能的图片广告实例
Feb 26 Javascript
javascript数组去重小结
Mar 07 Javascript
Vue声明式渲染详解
May 17 Javascript
Textarea输入字数限制实例(兼容iOS&amp;安卓)
Jul 06 Javascript
用户管理的设计_jquery的ajax实现二级联动效果
Jul 13 jQuery
layui.js实现的表单验证功能示例
Nov 15 Javascript
微信小程序new Date()方法失效问题解决方法
Jul 29 Javascript
Vue项目打包压缩的实现(让页面更快响应)
Mar 10 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和ACCESS写聊天室(四)
2006/10/09 PHP
利用Ffmpeg获得flv视频缩略图和视频时间的代码
2011/09/15 PHP
PHP数据库万能引擎类adodb配置使用以及实例集锦
2014/06/12 PHP
PHP二维数组去重实例分析
2016/11/18 PHP
PHP简单装饰器模式实现与用法示例
2017/06/22 PHP
php记录搜索引擎爬行记录的实现代码
2018/03/02 PHP
javascript 控制弹出窗口
2007/04/10 Javascript
JavaScript的继承的封装介绍
2013/10/15 Javascript
js动态调用css属性的小规律及实例说明
2013/12/28 Javascript
JavaScript模块随意拖动示例代码
2014/05/27 Javascript
简单纯js实现点击切换TAB标签实例
2015/08/23 Javascript
继续学习javascript闭包
2015/12/03 Javascript
整理JavaScript对DOM中各种类型的元素的常用操作
2016/05/05 Javascript
jQuery EasyUI学习教程之datagrid点击列表头排序
2016/07/09 Javascript
easyui datebox 时间限制,datebox开始时间限制结束时间,datebox截止日期比起始日期大的实现代码
2017/01/12 Javascript
Vuex之理解Store的用法
2017/04/19 Javascript
AngularJS 实现购物车全选反选功能
2017/10/24 Javascript
基于jQuery实现无缝轮播与左右点击效果
2018/05/13 jQuery
vue+mock.js实现前后端分离
2019/07/24 Javascript
解决vue elementUI中table里数字、字母、中文混合排序问题
2020/01/07 Javascript
如何区分vue中的v-show 与 v-if
2020/09/08 Javascript
python读取与写入csv格式文件的示例代码
2017/12/16 Python
Python基于百度AI的文字识别的示例
2018/04/21 Python
python爬虫开发之使用python爬虫库requests,urllib与今日头条搜索功能爬取搜索内容实例
2020/03/10 Python
Django 删除upload_to文件的步骤
2020/03/30 Python
python如何实现读取并显示图片(不需要图形界面)
2020/07/08 Python
MoviePy简介及Python视频剪辑自动化
2020/12/18 Python
python函数超时自动退出的实操方法
2020/12/28 Python
目前不被任何主流浏览器支持的CSS3属性汇总
2014/07/21 HTML / CSS
财务人员个人自荐信范文
2013/09/26 职场文书
应届大学生自荐信
2013/12/05 职场文书
人事主管岗位职责
2014/01/30 职场文书
《路旁的橡树》教学反思
2014/04/07 职场文书
2015年留守儿童工作总结
2015/05/22 职场文书
goland 清除所有的默认设置操作
2021/04/28 Golang
Pyhton爬虫知识之正则表达式详解
2022/04/01 Python