上面的代码,当我在页面上点击“测试”按钮时,只会触发一次computed中的num函数,同时它不会向watch中的num发送通知。
结果如下:
但是当我把b--改成b+=2,也只触发一次computed中的num函数,但是能向watch中的num发送通知。
结果如下:
按我的理解,计算属性中的内部的变量[a,b]发生变化后,会触发变量本身的Watcher,同时向computed中num的Watcher发送通知,此时应该使其进行两次getter函数,从而打印出两个“get!”,同时watch中的num也应由于computed中的num变化被触发两次。
但结果是vue很巧妙的避开了这些缺陷。
唯一能让我解释得通的说法就是:vue将数据变化的通知放入了微任务,在微任务执行完成后,下一轮的宏任务开始时,比较两个值的变化,此时必且仅会触发一次getter函数,同时再在此后比较前后两个值的变化,如果发生变化,则通知用户定义的watcher[num],否则跳过。
以上是我个人的理解,所以我想求证我的理解是否正确。如果正确,请大神们具体说下vue是如何将更新通知放入微任务的。如果不正确,麻烦各位讲一讲正确的流程。
万分感谢!
Vue 的数据更新确实是异步的。
所以你的例子里面,并不是 this.a 变化后立即更新计算函数 ==> num 变化触发对应的 watch 函数 ==> this.b 变化立即触发计算函数 ==> num 变化触发对应的 watch 函数。
下面是 Vue 文档中相关的部分,异步更新队列