First Approach
const list = reactive([1, 2, 3, 4, 5]);
const handleClick = () =>{
list.push(...[11, 12, 13, 14, 15]);
list.push(...[16, 17, 18, 19, 20]);
Promise.resolve().then(() => {
list.push(33)
});
};
Second Approach
const list = reactive([1, 2, 3, 4, 5]);
const handleClick = ()=>{
Promise.resolve().then(() => {
list.push(33)
});
list.push(...[11, 12, 13, 14, 15]);
list.push(...[16, 17, 18, 19, 20]);
};
the first function will trigger twice vue hooks onUpdated
, but the second will trigger once, can anyone tell me why, thanks
2
Answers
It is because
Vue
uses an optimization mechanism based onnextTick
to batch the updates.In your first approach, you are pushing a bunch of values to the reactive array, Which would trigger the
onUpdate
hook once. Then thePromise
resolves in a separate cycle, Which would trigger theonUpdate
again.But in the second approach, The
Promise
resolves before thepush
operations. Then the code pushes a couple more values to the array. The Vue’s reactivity mechanism detects this and does these entire operations in a single tick. That triggers theonUpdate
hook only once.More details: Why Vue will update only once when two reactive data mutation super close?
I think you have known that vue will update data once in a sync code, because vue collect all the changes data to a microtask,and there is another microtask
(Promise.resolve()) in your code, In the first Approach, the vue-microtask is created befor the Promise.resolve(),so the Promise.resolve() will run after the vue upadted function,and then vue upadted again after Promise.resolve() running.
In the second Approach,the vue-microtask is created after the Promise.resolve(), and when the vue-microtask running,the Promise has been resolved ,and the modify of list has been added to vue-microtask.