读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---}
为什么?
已解决
悬赏分:70
- 解决时间 2021-11-27 14:41
点赞 0反对 0举报 0
收藏 0
分享 0
回答1
最佳
-
你的理解是对的,但是验证的时候犯错了。你打印this之后在控制台查看到应该是像下面这样值是省略的,必须点开才能看到具体是什么值。
但当你一打开的时候其实就等同于访问了该属性,也就触发了getter,所以更新了值。其实你的想法是对的,但你应该像下面这么验证你的想法:<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Document</title> </head> <body> <div id="app"> <button @click="increment">increment</button> <p>{{count}}</p> <button @click="onClick">log this</button> </div> <script src="https://cdn.staticfile.org/vue/2.6.10/vue.min.js"></script> <script> new Vue({ el: '#app', data: { count: 1, }, computed: { msg() { console.log('update computed') return 'computed_' + this.count; } }, methods: { increment() { this.count++; }, onClick() { console.log(this) } }, }) </script> </body> </html>
我的computed msg依赖于count,并且我在更新computed时打印了一句话,你可以看看当count增加时会不会输出log就知道是否是立即更新的。当展开this中的msg属性时你会发现控制台输出了log。证明确实只有在访问属性时才会触发getter
支持 0 反对 0 举报2021-11-27 05:51