首页 > 编程知识 正文

vuex的五个属性,vue子组件监听父组件属性变化

时间:2023-05-03 05:26:58 阅读:16880 作者:3552

一般来说,对vue不太了解的人不能理解这个问题。

首先介绍vue的基本知识点:

watcher分为三类,lazy watcher和 user watcher和渲染watcher

每个计算属性都对应于lazy watcher对象。

每个watch对象的属性都对应于一个用户watch对象。

每个组件都对应于一个渲染watcher对象

每个data的属性都与dep对象相对应,dep对象用于收集watcher并向watcher通知更新。

简单来说就是当前属性的watcher管理对象,当获取data中的属性时,会触发属性的get方法,然后当前属性对应的dep对象会进行watcher收集操作,当更新data中的属性时,会触发属性的set方法,然后当前属性对应的dep对象会通知之前收集的watcher进行更新操作

那么,什么是lazy watcher?

观察vue的初始化过程时,您发现了一个重要的知识点: user watcher和渲染watcher在创建时执行watcher收集操作

详细过程是通过执行watcher get方法为watcher的value属性赋值。 get方法触发getter方法,getter方法获取user watcher的data中属性的值,在呈现watcher中执行更新组件的方法,在内部执行render方法也就是说,user watcher和渲染watcher的get方法获取data属性的值,即触发属性的get方法,并执行收集watcher的操作

vue是在beforeCreated和created之间对user watcher进行收集,

vue是在beforeMounted和mounted之间对渲染watcher进行收集

与计算属性对应的watcher是lazy watcher,在创建时不会收集watcher

问题是: http://www.Sina.com/http://www.Sina.com /

vue在什么时候会收集lazy watcher?

这里又有问题了。 如果计算属性正在侦听data的属性,且未使用该计算属性,并且未收集计算属性,则在更新data属性时,无法启动与计算属性对应的watcher来更新计算属性。 这个没问题吗?

作为结论,没有问题。 请尝试在计算属性的方法中加入断点并调试。 如果该页未使用此计算属性,则无论此计算属性方法使用的是data属性,还是更改此计算属性接收的data属性的值,计算属性方法都不会执行。 接收属性的dep对象表示尚未收集此计算属性的watcher对象

所以你会发现lazy watcher只有在使用的时候才会去收集,不使用的话就不会去收集。

vue改写了计算属性的get方法

如果该页首先使用计算属性值,则计算属性执行初始化操作,首先获取与计算属性对应的watcher对象,然后执行watcher对象的get方法以获取计算属性的值,然后执行watcher的vaar 在执行watcher对象的get方法时执行watcher的收集工作,最后执行watcher的收集工作

然后,如果返回获取的计算属性的值,则直接返回watcher的值。

计算属性是只读的,直接赋值将报告错误

初始化计算属性后,如果再次更改data中的属性,lazy watcher将开始更新,并使用相应的计算属性方法更新计算属性的值

假设模板只有一个计算属性变量,并且计算属性变量与一个data中的属性相关联。 此时,vue如何进行watcher收集工作? 为什么数据属性会更改并触发渲染watcher? 但是,此时模板中没有使用data的属性吗? 如果能理解这个问题的话,之后的计算属性只要监听计算属性就能很好地理解

结论:vue在用到计算属性的时候才会去收集watcher,那为什么watch属性对应的watcher要立刻收集?第一次收集渲染watcher时,首先将渲染watcher放在全局targetStack数组中,然后运行render函数,获取计算属性值,再计算property

atcher的收集工作,然后对应的data中的属性的dep对象里就会添加一个计算属性watcher,然后targetStack会将尾部的计算属性watcher弹出,这个时候targetStack还保存了一个渲染watcher作为全局的Dep.target对象,这个时候在计算属性重写的get方法里会判断Dep.target对象是否存在,就是targetStack数组是否为空的意思,如果不为空,就会获取计算属性关联的所有dep对象对当前Dep.target对象进行收集,就是对渲染watcher进行收集,所以data中的属性里面会收集到两个watcher对象,一个是计算属性watcher,一个是渲染属性watcher,对data中的属性进行修改时,会先执行计算属性watcher的更新方法更新计算属性的值,然后执行渲染watcher把更新后的值渲染到界面上.

简单说就是计算属性的get方法会帮助关联的data中的属性收集下一个watcher,所以如果模版中用到计算属性的话,计算属性里关联的data属性的dep对象会连续收集两个watcher,一个是计算属性watcher,一个是渲染watcher,

所以如果触发data中的属性,会先触发计算属性watcher更新计算属性的值,然后触发渲染watcher把更新后的计算属性的值渲染到界面上

理解了上面的信息,再理解vue一个计算属性如何监听另一个计算属性就没那么难了

假设计算属性B的计算方法里用到了计算属性A,计算属性A的计算方法里用到了data中的属性age

计算属性是没有对应的dep对象管理watcher的,计算属性是不能被修改的,所以直接修改计算属性值,不可能通知到他关联到的另一个计算属性,所以一个计算属性监听另一个计算属性严格上来说是错误的,计算属性B并不能监听计算属性B的修改

准确的说法是,计算属性A和计算属性B都监听了data中的属性age,age修改后,先通知了计算属性A对应的watcher对计算属性A的值进行了更新,之后再通知计算属性B对应的watcher对计算属性B的值进行了更新,因为这个时候A的值已经修改了,所以B用的是修改后A的值,所以看起来像是B的值因为A的值变化而变化,就是计算属性B对计算属性A进行了监听,这只是一种错觉

根据之前的结论,计算属性watcher是lazy watcher,用到时候才会去获取值,然后进行收集操作,所以如果当前页面没有用到计算属性B的值的话,就不会有任何监听操作

如果当前组件中用到了计算属性B,就会进行计算属性的初始化操作,这个期间进行了计算属性watcher的收集工作,会先把B watcher压入targetStack栈中,然后执行计算方法,因为计算方法会获取A的值,所以又会进行计算属性A的初始化操作,把A watcher压入targetStack栈中,然后执行A的计算方法,这个时候会获取age的值,然后触发age对应的dep对象将Awatcher收集起来,然后targetStack弹出Awatcher,然后获取A的值的get方法之后会判断当前targetStack栈是否为空,如果不为空会把栈顶的watcher收集到自己watcher关联的dep对象里,就是age对应的dep对象,然后获取计算属性A的值的过程完毕,之后拿到计算属性A的值后再返回计算属性B的值,然后targetStack弹出Bwatcher,结束

简单说就是获取计算属性B的值时,先判断计算属性A有没有进行初始化,如果没有先对计算属性A的watcher进行收集并且返回值,如果计算属性初始化过了的话就直接返回值

之后计算属性A的get方法会判断全局Dep.target是否有值,有的话会将Dep.target收集到自己关联的dep对象里

也就是说如果计算属性B里用到了计算属性A,在获取计算属性B的值的时候

计算属性A的get方法会执行自己关联的dep对象收集计算属性B的watcher的操作

然后data中的属性的dep对象里就会有两个连续的计算属性watcher A和B,当data中的属性改变时,会通知这两个计算属性watcher进行更新,因为计算属性A先更新,所以计算属性B更新的时候拿到的是更新后的A的值,所以看起来像是计算属性B监听了计算属性A

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。