经历了折磨的几小时,发现问题是直呼操蛋,为啥用console.log会出现这种问题。具体是什么呢?我直接说结论:在watch回调中打印一个数组会导致不按照vue的规则重复触发回调。
我们从Vue3侦听数组这部分来看,vue3是不会监听内部数组改变的,只有当栈地址发生变化时才会触发监听,或者使用deep选项深度监听。
这时的情况还是正常的:
只有一个watch called-0
,不错,符合vue3的规则。
但不幸的是,我修改一下出现了问题
可以看到每次push
和splice
都会触发watchEffect
,不过如果你将console.log
修改为print
就没啥事,还是正常的。或者将console.log(array)
修改为console.log(toRaw(array))
也是可以的。这就有问题了。
我们先看看为啥ref不能监听数组,可以看看这篇文章。具体原因不去深究。
大致就是因为没有去深度遍历数组内部的set,get,只是停留在对地址的监听上,当地址改变了才会触发set从而触发监听。
说了这么多,从刚才的问题分析,只可能是console.log的问题了,猜想就是console.log打印的时候会去获取数组的值,从而触发监听数组的get, 当我修改console.log(array)为console.log(array[2])是,点击三下才会多触发一次。
暂时不去探究那么深,先睡觉,很晚了。