读vue源码时,遇到了一个问题
访问computed中的属性时,这是其get触发的方法
if (watcher) {
if (watcher.dirty) {
watcher.evaluate()
}
if (Dep.target) {
watcher.depend()
}
return watcher.value
}
只有computedWatcher中的dirty为true时,才执行computed内的函数,此时访问了data中的数据,与computed建立了依赖联系,执行完dirty属性=false
当我改变相关data中属性的值时,data的set执行的只是
dep.notify()
---
notify () {
const subs = this.subs.slice()
for (let i = 0, l = subs.length; i < l; i++) {
subs[i].update()
}
---
update () {
this.dirty = true
//...
}
至此,并没有去计算computed中最新的值,而只是把watcher中的dirty设为true,当下次访问这个computed属性时,就会重新计算这个值
从我分析来看,当我在改变data中的值时,我此时并没有更新computed中的值,而我需要访问computed中的属性时才会更新。
但是从实践来看,并不是我想的这样
data: {
a: 1,
},
computed: {
update_a() {
return this.a + '---'
}
},
methods: {
sayHello() {
this.a++;
console.log(this)
}
}
------ 结果 ---
//Vue {a:2, update_a: 2---}
为什么?
你的理解是对的,但是验证的时候犯错了。你打印this之后在控制台查看到应该是像下面这样值是省略的,必须点开才能看到具体是什么值。
但当你一打开的时候其实就等同于访问了该属性,也就触发了getter,所以更新了值。其实你的想法是对的,但你应该像下面这么验证你的想法:
我的computed msg依赖于count,并且我在更新computed时打印了一句话,你可以看看当count增加时会不会输出log就知道是否是立即更新的。当展开this中的msg属性时你会发现控制台输出了log。证明确实只有在访问属性时才会触发getter