vue watch原理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了vue watch原理相关的知识,希望对你有一定的参考价值。
参考技术A 1、很多情况下,computed和watch可以实现相同的功能;2、当需要在数据变化时执行异步或开销较大的操作时,使用watch会更好一些。因为computed会立即返回,此时异步操作可能还没有完成;
3、因为数据是响应式的,使得watch有意义。并不是因为watch了才使得数据是响应式的。
4、使用immediate:true,会在初始化watch时就立即执行handler回调函数,而不用等下一次数据更新。
5、使用deep:true,才会递归监听对象的属性(如果监听的是对象或数组)。
在created函数调用之前,调用了initWatcher方法,(调用该方法时,若immediate为真,则会立即执行回调函数),为每一个watcher属性实例化了一个Watcher,new Watcher ,会传入监听的属性key、回调函数和options,包括handler、deep和immediate的值,实例化的结尾会调用watcher.prototype.get方法,该方法会获得值并返回,值存在watcher.value属性上。
Get函数(即autorun)的执行即导致了watcher被收集为依赖。至此成功的监听了属性。
Get时,如果deep为真,则会递归监听所有的属性。
在数据发生变化时,调用watcher.prototype.update方法,最终会执行第三步的get。
watch的watcher中的lazy和sync都为false,所以会执行queueWatcher.
第一步
第二步
第三步 watch的get方法
第四步 更新数据
第五步
Q:哪些对象是Watcher?
A :在源码中,看到三个地方会初始化Watcher对象。挂载组件(mountComponent方法)、初始化watch(initWatch方法)和初始化computed(initComputed方法)。
关于小程序使用watch监听数据变化的方法
众所周知,Vue中,可以使用监听属性 watch来观察和响应 Vue 实例上的数据变化,那么小程序能不能实现这一点呢?
监听器的原理,是将data中需监听的数据写在watch对象中,并给其提供一个方法,当被监听的数据的值改变时,调用该方法。??
我们需要用到Javascript中的Object.defineProperty()方法,来手动劫持对象的getter/setter,从而实现给对象赋值时(调用setter),执行watch对象中相对应的函数,达到监听效果。
Object.defineProperty()方法,会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
这里假定有多个页面需要监听需求,把监听方法写在app.js中,以便全局调用
onLaunch: function () , // 设置监听器 watch: function (ctx, obj) Object.keys(obj).forEach(key => this.observer(ctx.data, key, ctx.data[key], function (value) obj[key].call(ctx, value) ) ) , // 监听属性,并执行监听函数 observer: function (data, key, val, fn) Object.defineProperty(data, key, configurable: true, enumerable: true, get: function () return val , set: function (newVal) if (newVal === val) return fn && fn(newVal) val = newVal , )
然后,在需要监听的页面onLoad中,调用watch方法(其中test是要监听的数据,当test在其他方法中通过this.setData赋值后,watch就能监听到test的变化了)
const app = getApp() Page( data: test: 0 , onLoad: function () // 调用监听器,监听数据变化 app.watch(this, test: function (newVal) console.log(newVal) )
以上是关于vue watch原理的主要内容,如果未能解决你的问题,请参考以下文章