使用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函数的参数
Jul 16 Javascript
Bootstrap实现默认导航栏效果
Sep 21 Javascript
AngularJS 中的事件详解
Jul 28 Javascript
Bootstrap CSS布局之图像
Dec 17 Javascript
使用Vue开发一个实时性时间转换指令
Jan 17 Javascript
详解vue2.0监听属性的使用心得及搭配计算属性的使用
Jul 18 Javascript
vue.js实现的幻灯片功能示例
Jan 18 Javascript
layui使用表格渲染获取行数据的例子
Sep 13 Javascript
Vue获取页面元素的相对位置的方法示例
Feb 05 Javascript
Node.JS获取GET,POST数据之queryString模块使用方法详解
Feb 06 Javascript
canvas实现贪食蛇的实践
Feb 15 Javascript
Javascript webpack动态import
Apr 19 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替换字符串中间字符为省略号的方法
2015/05/04 PHP
PHP模拟asp.net的StringBuilder类实现方法
2015/08/08 PHP
PHP基于面向对象实现的留言本功能实例
2018/04/04 PHP
php微信公众号开发之微信企业付款给个人
2018/10/04 PHP
SyntaxHighlighter语法高亮插件使用说明
2011/08/14 Javascript
原生js做的手风琴效果的导航菜单
2013/11/08 Javascript
Select标签下拉列表二级联动级联实例代码
2014/02/07 Javascript
js仿淘宝和百度文库的评分功能
2016/05/15 Javascript
百度多文件异步上传控件webuploader基本用法解析
2016/11/07 Javascript
javascript 秒表计时器实现代码
2017/03/09 Javascript
JS仿QQ好友列表展开、收缩功能(第一篇)
2017/07/07 Javascript
在页面中引入js的两种方法(推荐)
2017/08/29 Javascript
Js利用Canvas实现图片压缩功能
2017/09/13 Javascript
swiper自定义分页器使用方法详解
2020/09/14 Javascript
图片懒加载imgLazyLoading.js使用详解
2020/09/15 Javascript
Vue组件通信的几种实现方法
2019/04/25 Javascript
Node Mongoose用法详解【Mongoose使用、Schema、对象、model文档等】
2020/05/13 Javascript
微信小程序实现带放大效果的轮播图
2020/05/26 Javascript
基于javascript处理二进制图片流过程详解
2020/06/08 Javascript
vue自定义指令限制输入框输入值的步骤与完整代码
2020/08/30 Javascript
如何搜索查找并解决Django相关的问题
2014/06/30 Python
Python中Class类用法实例分析
2015/11/12 Python
Python hashlib模块用法实例分析
2018/06/12 Python
django框架模型层功能、组成与用法分析
2019/07/30 Python
Python pandas实现excel工作表合并功能详解
2019/08/29 Python
python实现淘宝购物系统
2019/10/25 Python
Python魔术方法专题
2020/06/19 Python
摩顿布朗英国官方网上商店:奢华沐浴、身体和头发护理
2016/10/29 全球购物
新西兰便宜隐形眼镜购买网站:QUICKLENS New Zealand
2019/03/02 全球购物
骨干教师培训方案
2014/05/06 职场文书
积极向上的团队口号
2014/06/06 职场文书
学校党委副书记个人对照检查材料思想汇报
2014/09/28 职场文书
简易离婚协议书(范本)
2014/10/25 职场文书
员工离职感谢信
2015/01/22 职场文书
8g内存用python读取10文件_面试题-python 如何读取一个大于 10G 的txt文件?
2021/05/28 Python
SQL Server 中的事务介绍
2022/05/20 SQL Server