使用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 相关文章推荐
escape、encodeURI 和 encodeURIComponent 的区别
Mar 02 Javascript
jQuery实现类似滑动门切换效果的层切换
Sep 23 Javascript
javascript操纵OGNL标签示例代码
Jun 16 Javascript
让图片跳跃起来  javascript图片轮播特效
Feb 16 Javascript
javascript实现一个简单的弹出窗
Feb 22 Javascript
对angularJs中controller控制器scope父子集作用域的实例讲解
Oct 08 Javascript
seajs和requirejs模块化简单案例分析
Aug 26 Javascript
js实现橱窗展示效果
Jan 11 Javascript
vue实现带过渡效果的下拉菜单功能
Feb 19 Javascript
vue中实现回车键登录功能
Feb 19 Javascript
JS数组降维的实现Array.prototype.concat.apply([], arr)
Apr 28 Javascript
vue使用element-ui实现表单验证
Dec 13 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禁止个别IP访问网站
2013/10/30 PHP
php实现微信支付之现金红包
2018/05/30 PHP
javascript获取作用在元素上面的样式属性代码
2012/09/20 Javascript
js限制文本框输入长度两种限制方式(长度、字节数)
2012/12/19 Javascript
js 获取计算后的样式写法及注意事项
2013/02/25 Javascript
JS函数重载的解决方案
2014/05/13 Javascript
chrome下img加载对height()的影响示例探讨
2014/05/26 Javascript
JS+CSS实现感应鼠标渐变显示DIV层的方法
2015/02/20 Javascript
jquery.cookie.js用法实例详解
2015/12/25 Javascript
javascript实现简单计算器效果【推荐】
2016/04/19 Javascript
JS中innerHTML和pasteHTML的区别实例分析
2016/06/22 Javascript
VueRouter导航守卫用法详解
2017/12/25 Javascript
JavaScript中EventLoop介绍
2018/01/22 Javascript
详解使用jQuery.i18n.properties实现js国际化
2018/05/04 jQuery
angular4自定义表单控件[(ngModel)]的实现
2018/11/23 Javascript
微信小程序如何使用云开发
2019/05/17 Javascript
p5.js绘制旋转的正方形
2019/10/23 Javascript
vue-cli3访问public文件夹静态资源报错的解决方式
2020/09/02 Javascript
Python实现的用户登录系统功能示例
2018/02/05 Python
python3学习笔记之多进程分布式小例子
2018/02/13 Python
python 计算数据偏差和峰度的方法
2019/06/29 Python
在Python中构建增广矩阵的实现方法
2019/07/01 Python
django 控制页面跳转的例子
2019/08/06 Python
浅谈keras 的抽象后端(from keras import backend as K)
2020/06/16 Python
Links of London官方网站:英国标志性的珠宝品牌
2017/04/09 全球购物
美国轮胎网站:Priority Tire
2018/11/28 全球购物
英国计算机商店:Technextday
2019/12/28 全球购物
新西兰购物网站:TheMarket NZ
2020/09/19 全球购物
创新比赛获奖感言
2014/02/13 职场文书
工程建设实施方案
2014/03/14 职场文书
刑事辩护授权委托书
2014/09/13 职场文书
党员剖析材料范文
2014/09/30 职场文书
学校师德师风整改方案
2014/10/28 职场文书
护士求职简历自我评价
2015/03/10 职场文书
Python读写yaml文件
2022/03/20 Python
【TED出品】天梯非主流开心游1700 划水骑士
2022/03/31 魔兽争霸