使用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中将Object转换为String函数代码 (json str)
Apr 29 Javascript
获取表单控件原始(初始)值的方法
Aug 21 Javascript
jquery 通过name快速取值示例
Jan 24 Javascript
JavaScript中的call方法和apply方法使用对比
Aug 12 Javascript
JS+CSS实现简易的滑动门效果代码
Sep 24 Javascript
jQuery中通过ajax的get()函数读取页面的方法
Feb 29 Javascript
JavaScript输入分钟、秒倒计时技巧总结(附代码)
Aug 17 Javascript
移动端网页开发调试神器Eruda的介绍与使用技巧
Oct 30 Javascript
详解React Native 采用Fetch方式发送跨域POST请求
Nov 15 Javascript
vue初尝试--项目结构(推荐)
Jan 30 Javascript
angular异步验证器防抖实例详解
Mar 31 Javascript
Vue OpenLayer 为地图绘制风场效果
Apr 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 Try Catch异常测试
2009/03/01 PHP
PHP初学者常见问题集合 修正版(21问答)
2010/03/23 PHP
php中加密解密DES类的简单使用方法示例
2020/03/26 PHP
Flash对联广告的关闭按钮讨论
2007/01/30 Javascript
js获取html参数及向swf传递参数应用介绍
2013/02/18 Javascript
JS判定是否原生方法
2013/07/22 Javascript
jQuery图片缩放插件smartZoom使用实例详解
2017/08/25 jQuery
vue-cli脚手架build目录下utils.js工具配置文件详解
2018/09/14 Javascript
浅谈react-router@4.0 使用方法和源码分析
2019/06/04 Javascript
Python小工具之消耗系统指定大小内存的方法
2018/12/03 Python
Python3 pip3 list 出现 DEPRECATION 警告的解决方法
2019/02/16 Python
Django框架创建mysql连接与使用示例
2019/07/29 Python
python字符串反转的四种方法详解
2019/12/02 Python
python 画3维轨迹图并进行比较的实例
2019/12/06 Python
python Jupyter运行时间实例过程解析
2019/12/13 Python
pyinstaller 3.6版本通过pip安装失败的解决办法(推荐)
2020/01/18 Python
tensorflow对图像进行拼接的例子
2020/02/05 Python
Python class的继承方法代码实例
2020/02/14 Python
.img/.hdr格式转.nii格式的操作
2020/07/01 Python
css3类选择器之结合元素选择器和多类选择器用法
2017/03/09 HTML / CSS
英国床和浴室商场:Bed & Bath Emporium
2018/05/20 全球购物
FitFlop美国官网:英国符合人体工学的鞋类品牌
2018/10/05 全球购物
北卡罗来纳州豪华家具和家居装饰店:Carolina Rustica
2018/10/30 全球购物
食品业务员岗位职责
2014/03/18 职场文书
超市中秋节促销方案
2014/03/21 职场文书
给校长的建议书300字
2014/05/16 职场文书
新学期标语
2014/06/30 职场文书
普通党员个人整改措施
2014/10/27 职场文书
试用期工作表现自我评价
2015/03/06 职场文书
民事申诉状范本
2015/05/20 职场文书
早上好问候语大全
2015/11/10 职场文书
2016秋季小学开学寄语
2015/12/03 职场文书
医护人员继续教育学习心得体会
2016/01/19 职场文书
《吃水不忘挖井人》教学反思
2016/02/22 职场文书
pandas:get_dummies()与pd.factorize()的用法及区别说明
2021/05/21 Python
MySQ InnoDB和MyISAM存储引擎介绍
2022/04/26 MySQL