vue2如何查看什么导致了computed的重新求值/更新?

  computed: {

aaa() {

console.log(111);

debugger;

return this.bbb.map(item => this.一个方法(item, this.ccc));

},

aaa会莫名重新计算/调用/更新,不知道是什么导致的,如何快捷地找到是什么导致的

根据我建了个watch(deep)来看,this.bbb并没有变

我看了一些computed原理,但是都没有实际例子,只是在源码上分析,看不懂


添加断点后,看着往上第4层是这个函数

function createComputedGetter (key) {

return function computedGetter () {

var watcher = this._computedWatchers && this._computedWatchers[key];

if (watcher) {

if (watcher.dirty) {

watcher.evaluate();这里

}

if (Dep.target) {

watcher.depend();

}

return watcher.value

}

}

}

vue2如何查看什么导致了computed的重新求值/更新?
看起来似乎跟deps有点关系,但是不知道怎么看


回答:

监听一下:

watch: {

ccc(newVal, oldVal) {

console.log('ccc changed!', newVal, oldVal);

}

}


回答:

aaa 第一行 debugger
然后看每一次内部的变量数值就好了
甚至你可以从调用链向上翻出来从哪里开始的

计算函数没有问题
可能的原因:
1.对象重新赋值了,虽然数值是一样的但是有过 深拷贝,导致原来的引用不能用
2.有对 aaa 的赋值?非常规操作


回答:

最近研究了一下源码,大致懂了
从initComputed开始往后逐行看

到这里

  if (!isSSR) {

// create internal watcher for the computed property.

watchers[key] = new Watcher(//key是"aaa"

vm,

getter || noop,//getter是aaa这个函数,创建一个watcher实例

noop,

computedWatcherOptions

);

}

然后到
var Watcher = function Watcher (

vm,

expOrFn,

cb,

options,

isRenderWatcher

) {
里加断点

可以看到

this.value = this.lazy

? undefined

: this.get();//这里调用get方法

然后再继续到get里下断点
Watcher.prototype.get = function get () {

pushTarget(this);

var value;

var vm = this.vm;

try {

value = this.getter.call(vm, vm);//这里是关键,这里的this.getter就是aaa这个函数,有[[FunctionLocation]]可以点击跳转过去。//这就意味着这里会运行aaa这个函数。运行过程中,就会触发/调用 this.bbb和**this.ccc**的getter,然后就是下面这段话

触发了数据对象的 getter。
那么每个对象值的 getter 都持有一个 dep,在触发 getter 的时候会调用 dep.depend() 方法,也就会执行 Dep.target.addDep(this)。

所以,this.aaa的依赖就是运行aaa()这个函数过程中因为要获取值而触发getter的this.bbb和this.ccc,并不是只有this.bbb


至于另外一个问题的原因 “并且并不是c每次变都会使a重新计算(只有变c的某个特定的属性才会)”

因为这里computed相当于watch的deep: false,不会深度监听(调试源码下边这里能看到)

  // "touch" every property so they are all tracked as

// dependencies for deep watching

if (this.deep) {

traverse(value);

}

所以,因为ccc是引用/地址,并没有变,所以不是ccc改变导致的a重新计算,而是ccc里边的一个属性
至于是ccc里边的哪个属性,要看this.一个方法,在执行这个方法的过程中(通过getter)获取了ccc的哪个属性。我这里这个方法又调用了一个函数,在那个函数里才真正找到了获取ccc的一个属性的地方


另外一个关联问题https://segmentfault.com/q/1010000044357563
查看方法我目前还没搞出来,获取闭包的值有点困难


此外说一下调试vue源码的问题,一搜网上很多文章都是要下载源码npm安装依赖,重新构建sourcemap,实际上简单调试不需要这么麻烦,直接用打包好的https://cdn.jsdelivr.net/npm/vue@2.6.14/dist/vue.js
就行,这样只是打包成了一个单个的文件,没有min压缩,里边的函数名变量名什么的都是有的。只是没法改而已(打包出来dist/vue.js.map这个sourcemap文件后,应该也没法改的,只是有路径了


回答:

computed 中用到的响应式对象的值变化都会触发重新计算,你这里就去找哪些地方修改了 this.bbb, 和 this.ccc 就知道了

以上是 vue2如何查看什么导致了computed的重新求值/更新? 的全部内容, 来源链接: utcz.com/p/935129.html

回到顶部