使用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 相关文章推荐
简介JavaScript中setUTCSeconds()方法的使用
Jun 12 Javascript
jquery SweetAlert插件实现响应式提示框
Aug 18 Javascript
javascript实现tab切换的两个实例
Nov 05 Javascript
详解JavaScript正则表达式之RegExp对象
Dec 13 Javascript
有关JavaScript中call()和apply() 的一些理解
May 20 Javascript
深入浅析JS的数组遍历方法(推荐)
Jun 15 Javascript
JavaScript职责链模式概述
Sep 17 Javascript
浅析javascript中的Event事件
Dec 09 Javascript
微信小程序实现图片预览功能
Jan 31 Javascript
微信小程序scroll-view隐藏滚动条的方法详解
Mar 25 Javascript
VUE子组件向父组件传值详解(含传多值及添加额外参数场景)
Sep 01 Javascript
vue绑定class的三种方法
Dec 24 Vue.js
深入理解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
PHP更新购物车数量(表单部分/PHP处理部分)
2013/05/03 PHP
php-perl哈希算法实现(times33哈希算法)
2013/12/30 PHP
php使用百度ping服务代码实例
2014/06/19 PHP
jQuery 学习6 操纵元素显示效果的函数
2010/02/07 Javascript
js 多种变量定义(对象直接量,数组直接量和函数直接量)
2010/05/24 Javascript
jQuery隔行变色与普通JS写法的对比
2013/04/21 Javascript
对于Form表单reset方法的新认识
2014/03/05 Javascript
用IE重起计算机或者关机的示例代码
2014/03/10 Javascript
Bootstrap表单布局样式源代码
2016/07/04 Javascript
Html5+jQuery+CSS制作相册小记录
2016/12/30 Javascript
浅析jsopn跨域请求原理及cors(跨域资源共享)的完美解决方法
2017/02/06 Javascript
深入理解Angular.JS中的Scope继承
2017/06/04 Javascript
jquery单击文字或图片内容放大并居中显示
2017/06/23 jQuery
react-native中ListView组件点击跳转的方法示例
2017/09/30 Javascript
对vue.js中this.$emit的深入理解
2018/02/23 Javascript
vue-router懒加载速度缓慢问题及解决方法
2018/11/25 Javascript
修改vue源码实现动态路由缓存的方法
2020/01/21 Javascript
[48:21]林俊杰圣堂刺客超神杀戮秀
2014/10/29 DOTA
浅谈python中set使用
2016/06/30 Python
Tensorflow卷积神经网络实例进阶
2018/05/24 Python
python 猴子补丁(monkey patch)
2019/06/26 Python
Python中利用LSTM模型进行时间序列预测分析的实现
2019/07/26 Python
简单介绍django提供的加密算法
2019/12/18 Python
python自动点赞功能的实现思路
2020/02/26 Python
css3的动画特效之动画序列(animation)
2017/12/22 HTML / CSS
法国包包和行李箱销售网站:Bagage24.fr
2020/03/24 全球购物
大学生个人自荐信样本
2014/03/02 职场文书
酒店管理专业毕业生求职自荐信
2014/04/28 职场文书
期末评语大全
2014/05/04 职场文书
开服装店计划书
2014/08/15 职场文书
2014年党员加强作风建设思想汇报
2014/09/15 职场文书
镇人大副主席民主生活会对照检查材料思想汇报
2014/10/01 职场文书
个人买房协议书范本
2014/10/06 职场文书
销售内勤岗位职责
2015/02/10 职场文书
听证会主持词
2015/07/03 职场文书
使用php的mail()函数实现发送邮件功能
2021/06/03 PHP