Lifecycle hooks is executed in the wrong order.
Vue version
3.3.4
Link to minimal reproduction
https://stackblitz.com/edit/vitejs-vite-avbi9v?file=src%2FApp.vue
Steps to reproduce
- Click the
open:0
button - Click the
close
button - Click the
open:1
button
What is expected?
Console log:
open: 0
init => onBeforeMount
onBeforeMount => onMounted
onMounted => onBeforeUnmount
onBeforeUnmount => onUnmounted
close
init => onBeforeMount
onBeforeMount => onMounted
open: 1
init => onBeforeMount
onBeforeMount => onMounted
onMounted => onBeforeUnmount
onBeforeUnmount => onUnmounted
OR:
open: 0
close
init => onBeforeMount
onBeforeMount => onMounted
open: 1
What is actually happening?
Console log:
open: 0
init => onBeforeMount
onBeforeMount => onBeforeUnmount
onBeforeUnmount => onMounted
onMounted => onUnmounted
close
init => onBeforeMount
onBeforeMount => onMounted
open: 1
init => onBeforeMount
onBeforeMount => onBeforeUnmount
onBeforeUnmount => onMounted
onMounted => onUnmounted
System Info
System:
OS: macOS 13.4.1
CPU: (8) arm64 Apple M1
Memory: 83.78 MB / 16.00 GB
Shell: 5.9 - /bin/zsh
Binaries:
Node: 16.19.1 - /opt/homebrew/bin/node
Yarn: 1.22.19 - /opt/homebrew/bin/yarn
npm: 8.19.3 - /opt/homebrew/bin/npm
pnpm: 8.4.0 - /opt/homebrew/bin/pnpm
Browsers:
Chrome: 115.0.5790.114
Safari: 16.5.1
Any additional comments?
In this demo, Item's lifecycle hooks are sometimes executed in this order:
onBeforeMount->onBeforeUnmounted->onMounted->onUnmounted
There is a unit test to ensure the order is correct. It can be found below:
I'm uncertain how to reconcile your reproduction case with this. Something maybe wrong with your test case - I wouldn't expect onBeforeUnmount to be called at all when you click open.
The key point in reproducing the problem is effectiveVisible
Change modelRef.value?.effectiveVisible
to visible.value
can fix the demo:
const effectiveList = computed(() => list.value.filter(it => !visible.value || it !== selectedItem.value))
Console will print:
open: 0
close
init => onBeforeMount
onBeforeMount => onMounted
open: 1
same problem: element-plus#15145
Note: The Item.vue
component was unmounted during the mounting phase. IMO, the onMounted
hook should not be executed because the component was not actually successfully mounted. This is the same reason as #9264.
Maybe fixed by #9370
see demo base on #9370