小程序如何通过watch和computed检测数据

网友投稿 1001 2022-10-02

小程序如何通过watch和computed检测数据

小程序如何通过watch和computed检测数据

程序员必备接口测试调试工具:立即使用Apipost = Postman + Swagger + Mock + Jmeter Api设计、调试、文档、自动化测试工具 后端、前端、测试,同时在线协作,内容实时同步

在vue中,computed是一个计算属性,类似于过滤器,对绑定到view的数据进行处理,并监听变化。而watch监听复杂数据类型需用深度监听。这两者都可以在vue上实现检测数据的变化。而微信小程序不同于vue可以使用watch和computed做出相应的改变。小程序中只有函数this.setData()可以检测数据,所以小程序每次数据改变需要检测时都必须手动执行函数才可实现。除此之外,小程序还可以附上这两个功能检测数据变化。

vue 里是通过 Object.defineProperty 来实现数据变化检测的,给该变量的 setter 里注入所有的绑定操作,就可以在该变量变化时带动其它数据的变化。实际上,在小程序里实现要比 vue 里简单,应为对于 data 里对象来说,vue 要递归的绑定对象里的每一个变量,使之响应式化。但是在微信小程序里,不管是对于对象还是基本类型,只能通过 this.setData() 来改变,这样我们只需检测 data 里面的 key 值的变化,而不用检测 key 值里面的 key 。

测试代码:

Page({data: {test: { a: 123 },test1: \'test1\',},onLoad() {computed(this, {test2: function() {returnthis.data.test.a + \'2222222\'},test3: function() {returnthis.data.test.a + \'3333333\'}})watch(this, {test:function(newVal) {console.log(\'invoke watch\')this.setData({test1: newVal.a + \'11111111\' })}})},changeTest() {this.setData({ test:{ a: Math.random().toFixed(5) } })},})-

watch 方法相对简单点,首先我们定义一个函数来检测变化:

function defineReactive(data, key, val, fn) {Object.defineProperty(data, key, {configurable: true,enumerable: true,get: function() {return val},set: function(newVal){if (newVal === val)returnfn &&fn(newVal)val = newVal},})}-

然后遍历 watch 函数传入的对象,给每个键调用该方法

function watch(ctx, obj) {Object.keys(obj).forEach(key => {defineReactive(ctx.data, key, ctx.data[key], function(value) {obj[key].call(ctx,value)})})}-

这里有参数是 fn ,即上面 watch 方法里 test 的值,这里把该方法包一层,绑定 context。

接着来看 computed,这个稍微复杂,因为我们无法得知 computed 里依赖的是 data 里面的哪个变量,因此只能遍历 data 里的每一个变量。

function computed(ctx, obj) {let keys =Object.keys(obj)let dataKeys =Object.keys(ctx.data)dataKeys.forEach(dataKey => {defineReactive(ctx.data, dataKey, ctx.data[dataKey])})let firstComputedObj =keys.reduce((prev, next) => {ctx.data.$target =function() {ctx.setData({[next]: obj[next].call(ctx) })}prev[next] =obj[next].call(ctx)ctx.data.$target =null return prev}, {})ctx.setData(firstComputedObj)}-

详细解释下这段代码,首先给 data 里的每个属性调用 defineReactive 方法。接着计算 computed 里面每个属性第一次的值,也就是上例中的 test2、test3。

computed(this, {test2: function() {returnthis.data.test.a + \'2222222\'},test3: function() {returnthis.data.test.a + \'3333333\'}})-

这里分别调用 test2 和 test3 的值,将返回值与对应的 key 值组合成一个对象,然后再调用 setData() ,这样就会第一次计算这两个值,这里使用了 reduce 方法。test2 和 test3 都是依赖 test 的,这样必须在 test 改变的时候在其的 setter 函数中调用 test2 和 test3 中对应的函数,并通过 setData 来设置这两个变量。

小程序商店提供更多上线小程序

到此为止已经实现了 watch 和 computed,但是还没完,有个问题。当同时使用这两者的时候,watch 里的对象的键也同时存在于 data 中,这样就会重复在该变量上调用 Object.defineProperty ,后面会覆盖前面。因为这里不像 vue 里可以决定两者的调用顺序,因此我们推荐先写 computed 再写 watch,这样可以 watch computed 里的值。

推荐:《小程序开发教程》

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:计算机学院大学生程序设计竞赛(2015’11)1003 玩骰子
下一篇:计算机学院大学生程序设计竞赛(2015’12)The Magic Tower
相关文章

 发表评论

暂时没有评论,来抢沙发吧~