使用watch在微信小程序中实现全局状态共享


Posted in Javascript onJune 03, 2019

问题

在之前开发微信小程序的时候,获取用户信息、openid还有地理位置这些信息的时候,都是采用Promise的方式异步获取,但是这样的话在页面和App.js中都获取就可能造成请求重复的问题。

比如为了在每个页面都能获取到这些共享信息,都会选择在App.js中进行获取,然后在页面级进行获取,这两次获取的时间间隔较小时就可能导致前一个请求还未获取到数据,后一个请求就会再次进行获取,这样就产生了两次请求。

还有一个问题就是书写麻烦(虽然也能通过async await简化),比如

onLoad() {
 app.getUserInfo()
 .then(userInfo => {
 
 }).catch(err => { /* 错误处理 */ });
 
 // 如果同时需要userInfo和openid,可能就是如下形式:
 Promise.all([app.getUserInfo(), app.getOpenid()])
 .then(res => {
 
 }).catch(err => { /* 错误处理 */ });
}

正好周末的时候突然想到了vue的watch语法,利用一些相关的知识,就可以解决这个麻烦的问题了。

解决思路

双向绑定

vue的双向绑定原理,3.0将会采用Proxy监听数据变化,不过考虑到小程序这边的Proxy兼容性我不知道,所以采用了2.0的Object.defineProperty来监听数据的变化。

主要还是拦截设置的操作,在进行赋值时,将新旧值通知至监听者。

观察者模式

在页面级的onLoad监听app.globalData各个键名的事件,而在app.js的onLoad中则使用Object.defineProperty重新定义app.globalData,这样一旦app.globalData相应的键值发生了变化,就会通知监听的页面该值发生了变化。

模块化的引用

观察者模式导出的是一个对象(类实例),而不是一个类,所以在导入的时候这个对象是共享的,就可以通过这个对象将app.js和其他页面联系起来。

至于模块加载的实质,ES6模块加载的机制,与CommonJS模块完全不同。感兴趣的可以去看看这个。

封装Page

小程序的Page函数本身是不支持watch,但是我们可以自定义一个函数,进行参数合并就可以了。

在页面onLoad时先遍历watch属性,对app.globalData进行监听,可以参考vue的watch用法。

页面onUnload时就会进行销毁,此时也应该取消监听,这些我都封装过了,不用手动处理了。

有了这些思路,用不了多久,一个雏形就出来了,经过手动测试,感觉没什么问题,我就发布到npm了,大家感兴趣的可以安装体验一下。

安装

npm i wx-watch -S --production

使用

// app.js
var { watchData, } = require('/miniprogram_npm/wx-watch/index.js');

App({
 onLaunch() {
 this.watchData(); /* 监听this.globalData的变化,并触发事件,其他页面监听的值必须在globalData中预先定义,否则无法监听 */
 },
 watchData,
 globalData: {
 userInfo: null,
 }
});

// 其他需要监听globalData的页面.js
var { getPage } = require('../../miniprogram_npm/wx-watch/index.js');
const app = getApp();

/**
 * getPage(页面参数,app) app必传,因为封装的时候访问不到,就只能传参了
*/
getPage({
 watch: {
 userInfo(userInfo, oldUserInfo) {
 console.log(`来自app.glodalData的userInfo`);
 }
 },
 // 其他参数
}, app)

github:  github.com/ma125120/wx…

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对三水点靠木的支持。

Javascript 相关文章推荐
js的闭包的一个示例说明
Nov 18 Javascript
asp.net 30分钟掌握无刷新 Repeater
Sep 16 Javascript
jQuery+ajax中getJSON() 用法实例
Dec 22 Javascript
jQuery实现磁力图片跟随效果完整示例
Sep 16 Javascript
vue.js学习笔记之绑定style样式和class列表
Oct 31 Javascript
xmlplus组件设计系列之文本框(TextBox)(3)
May 03 Javascript
JavaScript数组_动力节点Java学院整理
Jun 26 Javascript
vue.js  父向子组件传参的实例代码
Oct 29 Javascript
vue2.0 + ele的循环表单及验证字段方法
Sep 18 Javascript
layui-table获得当前行的上/下一行数据的例子
Sep 24 Javascript
vue 解决uglifyjs-webpack-plugin打包出现报错的问题
Aug 04 Javascript
解决antd 下拉框 input [defaultValue] 的值的问题
Oct 31 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
微信小程序蓝牙连接小票打印机实例代码详解
Jun 03 #Javascript
react-native滑动吸顶效果的实现过程
Jun 03 #Javascript
You might like
全国FM电台频率大全 - 2 天津市
2020/03/11 无线电
CI框架实现优化文件上传及多文件上传的方法
2017/01/04 PHP
Laravel实现ApiToken认证请求
2019/10/14 PHP
面向对象的Javascript之一(初识Javascript)
2012/01/20 Javascript
JSON语法五大要素图文介绍
2012/12/04 Javascript
jquery实现滑屏大图定时收缩为小banner图片的广告代码
2015/09/02 Javascript
javascript跨域总结之window.name实现的跨域数据传输
2015/11/01 Javascript
JS 数字转换为大写金额的简单实例
2016/08/04 Javascript
微信小程序多张图片上传功能
2017/06/07 Javascript
深入理解vue2.0路由如何配置问题
2017/07/18 Javascript
angularjs实现时间轴效果的示例代码
2017/11/29 Javascript
JavaScript 正则命名分组【推荐】
2018/06/07 Javascript
在Create React App中启用Sass和Less的方法示例
2019/01/16 Javascript
新年快乐! javascript实现超级炫酷的3D烟花特效
2019/01/30 Javascript
JavaScript数组去重的方法总结【12种方法,号称史上最全】
2019/02/28 Javascript
微信小程序动态添加view组件的实例代码
2019/05/23 Javascript
在vant中使用时间选择器和popup弹出层的操作
2020/11/04 Javascript
Python使用sax模块解析XML文件示例
2019/04/04 Python
对python while循环和双重循环的实例详解
2019/08/23 Python
pywinauto自动化操作记事本
2019/08/26 Python
使用pandas的box_plot去除异常值
2019/12/10 Python
Python3基本输入与输出操作实例分析
2020/02/14 Python
python中xlutils库用法浅析
2020/12/29 Python
解决Python import .pyd 可能遇到路径的问题
2021/03/04 Python
关于 HTML5 的七个传说小结
2012/04/12 HTML / CSS
学徒工职责
2014/03/06 职场文书
学生请假条格式
2014/04/11 职场文书
活动策划求职信模板
2014/04/21 职场文书
钱塘江大潮导游词
2015/02/03 职场文书
2015年社区卫生工作总结
2015/04/21 职场文书
在酒桌上的敬酒词
2015/08/12 职场文书
全国劳模先进事迹材料(2016精选版)
2016/02/25 职场文书
陶瓷类经典广告语集锦
2019/10/25 职场文书
用python自动生成日历
2021/04/24 Python
DE1103使用报告
2022/04/05 无线电
SQL Server数据库备份和恢复数据库的全过程
2022/06/14 SQL Server