首页 > 热点 > 微信 > 正文

150行代码带你实现微信小程序中的数据侦听

2024-07-22 01:18:27
字体:
来源:转载
供稿:网友

在小程序项目中, 我们的通常会使用到使用到一个全局对象作为各个页面通用的数据存储容器, 将它绑定到app对象后, 就能在每一个页面都自由的操纵这个对象. 然而在实践中, 由于这个对象及其属性不具备响应式条件, 它不能直接参与业务逻辑的编写, 能力仅仅局限于数据储存. 若是在VueJS项目中, 我们可能经常使用到 Vue.$watch 去侦听某个数据是否发生变化, 小程序却缺乏这种能力.

在这篇文章中, 我将用150行代码, 手把手带你打造一个小程序也可以使用的侦听器(下简称VX):

// 一个快速赋值的语法糖函数, 可以创建结构为 { value: a { b: { val: ''} } } 的对象vx.set('value.a.d', { val: '' })// 对某个属性进行侦听, 如果发生改变, 则执行相应函数(可多次watch以执行多个函数)vx.watch('value.a.d.val', newVal => { console.log(`val改变为 : `, newVal)})value.a.d.val = 3 // val改编为 : 3

使用VX侦听器, 我们可以更加方便的管理各个页面的状态. 同时, 我们凭借 watch 语法, 可以更优雅地编写业务逻辑.

坐稳了, 三轮车准备启动了~ 各位评论见~ :yum:

稍微理一理思路

在全局对象中, 我们不一定要对每一个属性都进行侦听, 所以VX主要的功能就是通过set去设置某个具体属性的setter/getter, 同时通过watch向添加该属性添加需要订阅的回调函数.

依赖对象的实现

首先我们需要造一个通用的 依赖对象 , 依赖对象携带一个订阅数组用于存放一组回调函数, 同时它还应该包括一些操作订阅数组能力(如添加订阅, 清空订阅)的函数

class Dep { constructor () { this.subs = [] } // 将回调添加到数组中 addSub (fn) { /*...*/ } delSub (fn) { /*...*/ } // 执行数组中每一项函数 notify (newVal, oldVal) { this.subs.forEach(func => func(newVal, oldVal)) }}

全局对象中每一个响应式属性(及其每一个子属性), 都应该和一个新的Dep实例保持一一对应的关系, 这样我们进行侦听变化, 执行订阅的回调函数时, 只需要找到对应的实例执行 notify 通知更新即可.

设置响应式属性

defineProperty

可能是因为接触DefineProperty要比接触Proxy早一些的缘故, 代码使用了前者进行响应式的实现, Object.defineProperty方法会直接在一个对象上定义一个新属性, 这里快速过一遍 defineProperty 具体配置:

// @param obj 要在其上定义属性的对象// @param key 要定义或修改的属性的名称Object.defineProperty(obj, key, { // 该属性是否能被枚举 enumerable: true, // 该属性能否被删除 configurable: true, // 访问该属性则会执行此方法 get: () => { return val }, // 修改该属性时会执行此方法 set: newVal => { val = newVal }, // value & writeble 不能和 getter/setter 同时出现})            
发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表