Code前端首页关于Code前端联系我们

watch在微信小程序开发中实现了全局状态共享

terry 2年前 (2023-09-23) 阅读数 65 #移动小程序

开发微信小程序时,收到用户信息、openid、地理位置信息时,会与Promise异步接收。但在这种情况下,可能会导致页面和 app.js 上重复请求的问题。

例如,要在每个页面上获取此共享信息,您选择在App.js中获取它,然后在页面级别获取它。如果两次获取的时间间隔较小,仍然可以恢复之前的查询。如果没有收到数据,则再次收到下一个请求,从而产生两次请求。

另一个问题是编写困难(虽然也可以通过异步等待来简化)。比如

onLoad() {
    app.getUserInfo()
    .then(userInfo => {
        
    }).catch(err => { /* 错误处理 */ });
    
    // 如果同时需要userInfo和openid,可能就是如下形式:
    Promise.all([app.getUserInfo(), app.getOpenid()])
    .then(res => {
        
    }).catch(err => { /* 错误处理 */ });
}
复制代码

周末突然想到了Vue的watch语法。有了一些相关的知识,我就可以解决这个烦人的问题了。 。

解决方案

双向绑定

Vue的双向绑定原理,3.0会使用代理来监听数据变化,但是考虑到小程序的代理兼容性我不知道,所以采用了2.0。 Object.defineProperty来监视数据变化。

主要拦截设置操作。当您分配值时,新值和旧值将传递给侦听器。

观察者模式

在页面级别onLoad监听应用程序中app.globalDataj每个键名的事件。 .defineProperty 重新定义app.globalData,这样一旦app.globalData对应的key值发生变化,就会通知监听页面该值发生了变化。

模块化参考

观察者模式导出的是一个对象(类实例),而不是一个类,所以导入时这个对象是共享的,你可以使用这个对象来结合app.js和其他页面进行链接。

从模块加载的本质来看,ES6模块加载的机制与CommonJS模块完全不同。如果你有兴趣,你可以看看这个。

封装Page

小程序的页面函数本身不支持时钟,但我们可以自定义一个函数并合并参数。

页面onLoad时,首先运行监控属性,监控app.globalData。您可以参考查看时钟使用情况。

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…

作者:ma125120
e5jin。 3013e
来源:掘金
版权归作者所有。如需商业转载,请联系求作者授权。非商业转载请来源。

版权声明

本文仅代表作者观点,不代表Code前端网立场。
本文系作者Code前端网发表,如需转载,请注明页面地址。

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。

热门