交流群:462197261站长百科站长论坛热门标签收藏本站北冥有鱼 互联网前沿资源第一站 助力全行业互联网+
点击这里给我发消息
  • 当前位置:
  • 使用watch在微信小程序中实现全局状态共享

    问题

    在之前开发微信小程序的时候,获取用户信息、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…

    总结

    以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,谢谢大家对北冥有鱼的支持。

    您可能感兴趣的文章:

    • 在微信小程序里使用watch和computed的方法
    • 微信小程序在其他页面监听globalData中值的变化
    • 微信小程序全局变量改变监听的实现方法
    • JS实现监控微信小程序的原理
    • 微信小程序 监听手势滑动切换页面实例详解
    • 微信小程序 实现拖拽事件监听实例详解
    • 小程序使用watch监听数据变化的方法详解

    广而告之:
    热门推荐:
    jQuery弹出层插件Lightbox

    网站开发过程中,为了增加网站交互效果,我们有时需要在当前页面弹出诸如登陆、注册、设置等窗口。而这些窗口就是层,弹出的窗口就是弹出层。jQuery中弹出层插件很多,但有些在html5+css3浏览器下,支持完美。而在例如ie8一下的浏览器下显示不出应有的效果。例如jquery.avgrund···

    JS实现图片点击后出现模态框效果

    很多时候我们在浏览图片时,会发现点击图片后,会弹出一个被点击图片的放大图片浮在页面上,占满整个窗口。这就是图片模态框效果。 这个效果可以使用某些js库实现,如bpopupJs。但是在这里我们使用纯js实现,能够更好理解效果原理和实现方法。 一.实现思路 我们点击小图片之后,···

    javascript 表单日期选择效果

    Agenda BODY { FONT-SIZE: 9pt; PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 0px; PADDING-TOP: 0px; } A { FONT-SIZE: 9pt; TEXT-DECORATION: none; color: #000000 } A:hover { TEXT-DECORATION: none; color: #000000 } A:li···

    如何优化Mysql千万级快速分页

    看例子: 数 据表 collect ( id, title ,info ,vtype) 就这4个字段,其中 title 用定长,info 用text, id 是逐渐,vtype是tinyint,vtype是索引。这是一个基本的新闻系统的简单模型。现在往里面填充数据,填充10万篇新闻。 最后collect 为 10万条记录,数据库表占用硬盘1.6G···

    通过优化网页页面降低对内存及CPU的占用

      有的网页看起来并不大但打开会很卡,有的网页虽然很长但使用流畅,占用用户电脑的内存与CPU就影响这些。  浏览器问题,有各自的浏览器处理内存问题会影响到,但几乎没办法控制得了,Windows上的:  ·IE系列,刷新回收的量不大,但最小化会释放内存。  &···

    基于unique与primary约束的区别分析

    定义了UNIQUE约束的字段中不能包含重复值,可以为一个或多个字段定义UNIQUE约束,因此,UNIQUE即可以在字段级也可以在表级定义,在UNIQUE约束的字段上可以包含空值. ORACLE自动会为具有PRIMARY KEY约束的字段(主码字段)建立一个唯一索引和一个NOT NULL约束,定义PRIMARY KEY约···

    JS版元素周期表实现方法

    本文实例讲述了JS版元素周期表实现方法。分享给大家供大家参考。具体如下: 这里的元素周期表基于JavaScript实现,未使用任何的图片,直接浏览本HTML网页即可看到效果,可以作为教学使用。 运行效果如下图所示: 具体代码如下: <html> <head> <style type="t···

    浅谈一些SEO用力不用脑的后果

     前几天发了个微博,感慨如下:   有太多人,只知道羡慕别人的成就,却看不见别人的汗水,这已经被无数鸡汤文提到;那么也有不少人,汗水付出也很多,加班很辛苦,累的七死八活,但是依然没有什么太好的成绩,我想说,这里除了部分人运气不佳,大部分是“用力不···

    PHP和JAVA中的重载(overload)和覆盖(override) 介绍

    重载:同一个类中,函数名一样,返回值或者参数类型,个数不一样的叫做重载。 覆盖:同名函数,同返回值类型,同参数的叫做覆盖。指的是子类对父类中方法的覆盖。 PHP不支持方法和操作符重载。JAVA不支持操作符的重载(但是“+”实际上是一种操作符重载)。 复制代码 代码···

    AngularJS中比较两个数组是否相同

    Javascript不能直接用==或者===来判断两个数组是否相等,无论是相等还是全等都不行,以下两行JS代码都会返回false <script type="text/javascript"> alert([]==[]); alert([]===[]); </script> 要判断JS中的两个数组是否相同,需要先将数组转换为字符串,再作比较···