小程序对某个对象实现深度监听

1|0场景

  • 有一个与页面实例不关联的外部对象,当其某个属性改变时,需要页面做出反应,也就是页面需要监听它

2|0问题

  • 肯定直接想到计算属性,但是小程序不自带,然后用wx-computed等插件,发现都有缺陷,只能对页面实例内部data的属性进行监听
  • 然而就算把这个外部对象声明到page的data里,但由于对象属性的改变不是响应式的,这在vue里还能通过$set来解决,但是没有$set就只能想办法自己实现对该外部对象的深度监听

3|0解决

  • 在app.js中定义全局的监听函数

    App({ onLaunch: function () { console.log('app running') }, // 设置监听器 // ctx表示上下文,aim表示监听的目标对象,一般情况非深度监听没有aim参数,而是直接对ctx监听 // keys表示监听的目标对象的目标属性,其值是一个函数,也就是监听到其变化后触发的回调,然后call ctx给回调 watch: function (ctx, aim, keys) { Object.keys(keys).forEach(key => { this.observer(aim, key, aim[key], function (value) { keys[key].call(ctx, value) }) }) }, // 监听属性,并执行监听函数 observer: function (data, key, val, callback) { Object.defineProperty(data, key, { configurable: true, enumerable: true, get: function () { return val }, // 重写set函数,就能在其属性改变时触发回调 set: function (newVal) { if (newVal === val) return callback && callback(newVal) val = newVal }, }) } })
  • 然后在需要使用的page实例中引入

    const app = getApp() // 这里的上下文直接传this,Obj就是需要监听的外部对象,监听的属性是objProperty,然后页面在回调里做出响应 app.watch(this, Obj, { objProperty: function (newVal) { if (newVal) { this.setData({ pageVar: newVal }) } } })
  • 但是这里笔者也没有实现完全深度监听,比如上面监听的objProperty如果又是一个对象,就又出现了同样的问题,objProperty的某个属性改变不是响应式的,这时候就要在watch的定义里,对aim[key]判断是否是对象,如果是,需要递归一下,就能完全深度监听了


__EOF__

本文作者Mizuki
本文链接https://www.cnblogs.com/mizuki-vone/p/17380912.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   Mizuki-Vone  阅读(178)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· 清华大学推出第四讲使用 DeepSeek + DeepResearch 让科研像聊天一样简单!
· 实操Deepseek接入个人知识库
· CSnakes vs Python.NET:高效嵌入与灵活互通的跨语言方案对比
· Plotly.NET 一个为 .NET 打造的强大开源交互式图表库
点击右上角即可分享
微信分享提示