Reputation: 761
I would like to set a object property inside a for
-loop, and watch for those changes, but somehow Vue simply doesn't listen to all changes on the watch
prop.
Here is my test code to simplify my issue (https://jsfiddle.net/hn2wepc9/).
If you click on the button, it should log 5 lines in the console (because of the loop
method), but it only logs 1. I don't understand why Vue simply doesnt listen to all changes when I use Vue.set()
inside a for
loop and try to watch these changes.
<div id="app">
<button @click="loop">Button</button>
</div>
new Vue({
el: '#app',
data: () => {
return {
obj: {
name: 'John Doe'
}
}
},
methods: {
loop() {
for (let i = 0; i < 5; i++) {
Vue.set(this.obj, 'name', 'Dohn Joe ' + i);
}
}
},
watch: {
obj: {
deep: true,
handler(newVal, oldVal) {
window.console.log(newVal.name + ' - ' + new Date().toLocaleString());
}
}
}
});
Upvotes: 2
Views: 1190
Reputation: 138256
By default, watchers are run asynchronously (in the next macro tick) as a performance optimization. I think the motivation is watchers are assumed to only care about the most recent change.
You can configure the watcher to be synchronous by setting the sync
flag (one of several undocumented watch
flags):
watch: {
obj: {
sync: true
}
}
For reference, in Vue 3, the flag is called flush
with pre
, post
, and sync
as possible values. See Effect flush timing.
Upvotes: 3