使用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实现倒计时(距离结束还有)示例代码
Jul 24 Javascript
js读取注册表的键值示例
Sep 25 Javascript
js与jQuery 获取父窗、子窗的iframe
Dec 20 Javascript
jQuery操作JSON的CRUD用法实例
Feb 25 Javascript
基于JavaScript获取鼠标位置的各种方法
Dec 16 Javascript
原生JavaScript实现滚动条效果
Mar 24 Javascript
JavaScript实现页面跳转的方式汇总
May 16 Javascript
使用Promise解决多层异步调用的简单学习心得
May 17 Javascript
Vue数据驱动模拟实现3
Jan 11 Javascript
基于Vue的文字跑马灯组件(npm 组件包)
May 24 Javascript
微信小程序movable view移动图片和双指缩放实例代码
Aug 08 Javascript
JS实现倒序输出的几种常用方法示例
Apr 13 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
php 论坛采集程序 模拟登陆,抓取页面 实现代码
2009/07/09 PHP
PHP empty函数报错解决办法
2014/03/06 PHP
php文件包含目录配置open_basedir的使用与性能详解
2017/04/03 PHP
Javascript 面向对象 对象(Object)
2010/05/13 Javascript
阻止事件(取消浏览器对事件的默认行为并阻止其传播)
2013/11/03 Javascript
原生js的弹出层且其内的窗口居中
2014/05/14 Javascript
再谈javascript原型继承
2014/11/10 Javascript
js判断当前页面用什么浏览器打开的方法
2016/01/06 Javascript
轻松实现JavaScript图片切换
2016/01/12 Javascript
JavaScript正则表达式匹配 div  style标签
2016/03/15 Javascript
javascript的理解及经典案例分析
2016/05/20 Javascript
jQuery层级选择器实例代码
2017/02/06 Javascript
Javascript实现跨域后台设置拦截的方法详解
2017/08/04 Javascript
Bootstrap Table 搜索框和查询功能
2017/11/30 Javascript
详解Angular结合zTree异步加载节点数据
2018/01/20 Javascript
JS实现可针对算术表达式求值的计算器功能示例
2018/09/04 Javascript
JS实现灯泡开关特效
2020/03/30 Javascript
python进阶教程之模块(module)介绍
2014/08/30 Python
Python遍历指定文件及文件夹的方法
2015/05/09 Python
Linux下用Python脚本监控目录变化代码分享
2015/05/21 Python
python机器学习之神经网络(三)
2017/12/20 Python
python数据挖掘需要学的内容
2019/06/23 Python
Python将文字转成语音并读出来的实例详解
2019/07/15 Python
python3 requests库实现多图片爬取教程
2019/12/18 Python
史蒂夫·马登加拿大官网:Steve Madden加拿大
2017/11/18 全球购物
Gtech官方网站:地毯清洁器、吸尘器及园艺设备
2018/05/23 全球购物
北京某公司的.net笔试题
2014/03/20 面试题
音乐学院硕士生的自我评价分享
2013/11/01 职场文书
网站设计师的岗位职责
2013/11/21 职场文书
军训自我鉴定范文
2014/02/13 职场文书
2014年最新大专生职业生涯规划书范文
2014/09/13 职场文书
社区国庆节活动总结
2015/03/23 职场文书
爱国电影观后感
2015/06/19 职场文书
小型婚礼主持词
2015/06/30 职场文书
JavaScript offset实现鼠标坐标获取和窗口内模块拖动
2021/05/30 Javascript
源码安装apache脚本部署过程详解
2022/09/23 Servers