VIP用户交流群:462197261 收藏本站北冥有鱼 互联网前沿资源第一站 助力全行业互联网+
在线客服:78895949
tonglan
  • 当前位置:
  • 使用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监听数据变化的方法详解

    广而告之:
    热门推荐:
    详解JavaScript的变量

    基本类型和引用类型的值 ECMAScript变量一般有两种数据类型的值:基本类型和引用类型。 基本类型: 简单的数据段:Undefined, Null, Boolean, Number, String 引用类型:多个值构成的对象; 1.动态的属性 定义两者的值:创建一个变量并为其变量赋值; 执行两者的值: 引用类···

    WordPress管理页面底部自定义文字的方法

    本文实例讲述了在WordPress管理页面底部自定义文字的方法,分享给大家供大家参考。具体实现方法如下: 把下面的代码复制到主题functions.php文件中: 复制代码代码如下:<?php function example_footer_admin () { echo '<p style="color:red;">想要的文字(www.jb51.ne···

    WordPress中函数get_term_link的参数设置问题

    为何要用 get_term_link?: 新类型的分类是无法用 <?php echo get_category_link( $category_id ); ?> 输出分类链接地址的,需要用 get_term_link() 函数,此函数用法如下: <?php get_term_link( $term, $taxonomy ); ?> 具体参考 WordPress Codex:http://codex.···

    防采集功能使用说明

    1.开启防采集功能:参数设置-》信息设置 2.增加随机防采集字符:插件治理-》防采集随机字符治理(只要字符不能显示出来都可以加。字符越多防采的效果越好) 3.在内容模板需要显示随机字符的地址地方加上:"<!--ecms.*-->"即可 附加说明:一般把"<!--ecms.*-->"放···

    全面理解line-height与vertical-align

    前面的话   line-height、font-size、vertical-align是设置行内元素布局的关键属性。这三个属性是相互依赖的关系,改变行间距离、设置垂直对齐等都需要它们的通力合作。在CSS字体里面已经详细介绍了font-size的相关内容,本文将主要介绍line-height与vertical-align。 line···

    JavaScript实现随机数生成器(去重)

    本文实例为大家分享了js实现随机数生成器的具体代码,供大家参考,具体内容如下 1.实验前准备: Math函数的理解 数组方法的理解 2.实验操作: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>随机数生成</t···

    用DBSQL类加快开发MySQL数据库程序的速度

    当你在编写存取MYSQL的数据库程序时,是不是觉得很麻烦:一大套的函数和参数,还要检查调用的结果,更头痛的是每个程序里都要包含数据库名、用户、密码等,想修改都不容易。但如果你使用PHPLIB里的DBSQL类,这些问题都会迎刃而解的。这篇文章将教你如何使用DBSQL类。&nbs···

    elementUI中Table表格问题的解决方法

    前言 element ui是一个非常不错的vue的UI框架,element对table进行了封装,简化了vue对表格的渲染。 在开发vue框架项目时,引入element插件,使用table表格组件时,遇到了一些问题,以下列出以供参考。 1.表格样式问题: 混乱样式.png 正常样式.png 如上图,在当前导航表格t···

    加强版phplib的DB类

    复制代码 代码如下:<?php /**************************************************************************************************************** 为了便于自己的开发,又不想使用ADODB、PEAR::DB这样的庞然大物, 就用在PHPLib DB类的基础上、参考PEAR::DB类,···

    vue 点击按钮增加一行的方法

    如下所示: data() { return { customized_descs: [1], } }, 不要js,jq里面的方法了。 以上这篇vue 点击按钮增加一行的方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持北冥有鱼。 您可能感兴趣的文章: vue.js 1.x与2.0中js实时监听input···