Subscribe on changes!

dynamicChildren are unmounted multiple times in some cases

avatar
Oct 1st 2020

Version

3.0.0

Reproduction link

https://codepen.io/basvanmeurs/pen/xxVoYVE?editors=1111

Steps to reproduce

Just run and view the console log

What is expected?

"MyTest umounted" is shown once

What is actually happening?

"MyTest umounted" is shown twice


I encountered this one when I had a onBeforeUnmounted hook that couldn't handle being run twice. Then after debugging I found that it was run even 4 times.

Digging further I found out that this only happened in case of a component, wrapped into a parent div that has at least one (dynamic) property that references a setup var.

Digging even further I found that what happens is, that when a setup var is being used the patchFlag for that vnode is set to 8. When that happens, it gets added to the dynamicChildren of the encapsulating block, together with the vnode for my-test.

Then later, when unmounting, the code ends up here: https://github.com/vuejs/vue-next/blob/1abcb2cf61ec16807cae11cfe56acefab19487a1/packages/runtime-core/src/renderer.ts#L2029

First the vnode for my-tests gets unmounted, calling onBeforeUnmounted in the process. Then, next, the wrapper div is also unmounted. But because it also has the my-tests vnode as a child, that is unmounted again later, resulting in another onBeforeUnmounted invocation.

Notice that the component isn't patched double because of the 'optimized' arg that's passed to the patcher which refrains it from patching its children. Maybe a similar approach can be used to prevent double unmounting of dynamicChildren.

avatar
Oct 3rd 2020