浅析Vue中的$watch方法原理

发布网友 发布时间:2024-09-26 17:52

我来回答

1个回答

热心网友 时间:18小时前

$watche方法的两个参数:

第一个参数两种可能:

传入被观察对象表达式(字符串),比如'a,b,c','$route'

如果表达式无法表示需要观察的内容,可以通过函数返回,比如:()=>this.a+this.b

第一个参数干什么用的?通过vue源码可得,newWatcher的流程:第一步:拿到第一个参数,如果是函数,直接拿到函数,如果不是函数,转换为函数(parsePath),这个作为getter,先不调用,只备用

//parseexpressionforgetterif(typeofexpOrFn==='function'){this.getter=expOrFn}else{this.getter=parsePath(expOrFn)if(!this.getter){this.getter=noop//noop就是空}}

第二步:调用Watcher类里的this.get:

this.value=this.lazy?undefined:this.get()

插入下源代码:

/***Evaluatethegetter,andre-collectdependencies.*/get(){pushTarget(this)letvalueconstvm=this.vmtry{value=this.getter.call(vm,vm)}catch(e){if(this.user){handleError(e,vm,`getterforwatcher"${this.expression}"`)}else{throwe}}finally{//"touch"everypropertysotheyarealltrackedas//dependenciesfordeepwatchingif(this.deep){traverse(value)}popTarget()this.cleanupDeps()}returnvalue}

第三步:上面的源码就是this.get方法,看看里面有什么,这里第一句就是把当前watcher实例设置成Dep.target(姑且理解为全局变量),:

pushTarget(this)

关于Dep.target:回忆一下,在defineProperty的get里,是不是也用到了这Dep.target,对了!defineProperty里就是取这个Dep.target值,watcher只有一处取值,一处赋值,那么这个值在哪里赋上去的呢?对了!就是在这个pushTarget里

第四步:Dep.target已经有值了,调用一下之前备用的getter(上面第一步),这样就能触发defineProperty的get了,触发以后,就把这个watcher添加到get对应数据的deps依赖数组里了

value=this.getter.call(vm,vm)

这样,再修改这个设置了defineProperty的响应式数据,就能触发这个数据绑定的所有watcher依赖了。

声明声明:本网页内容为用户发布,旨在传播知识,不代表本网认同其观点,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。E-MAIL:11247931@qq.com