I'm facing a consistent behavior in vue.js and could not find any documentation describing it, and what I would like to know is if this behavior is expected or not.
I'm developing an SPA using vue.js 2.6.8, @vue/cli-service 3.5.1, and vue-router 3.0.1.
My routes look like this:
{
path: '/Users',
name: 'Users',
component: Users,
meta: {requiresAuth: true},
children: [
{
path: 'New',
component: NewUserModal,
name: 'NewUserModal',
meta: {requiresAuth: true},
}
]
},
{
path: '/Users/:id',
component: User,
name: 'User',
meta: {requiresAuth: true}
}
The Users component is a listing of users and has a router-view inside it in order to render the new user modal, looking like this:
<template>
<my-list-component>
<template #modal>
<router-view/>
</template>
</my-list-component>
</template>
Inside this component the user can click a button to push a new route, NewUserModal, then a modal is shown where one can create a new user and after the operation is completed another router push happens, so the user is redirected to the User route. In short:
Users -> NewUserModal -> User
All stages of the NewUserModal happen, it is indeed destroyed. However, if I ever go back to the Users component the DOM element of NewUserModal is still there, so I see the DOM of a destroyed child component on the parent.
I have the impression that the route change occurred "too fast" and when the destroy method of NewUserModal component is invoked the DOM element that it needs to destroy is not present in the page anymore, so it cannot remove it.
As a workaround I placed a the following code inside NewUserModal:
beforeDestroy() {
this.$el.remove();
},
And everything works just fine. So, is this the expected behavior of vue? Am I missing something? And more importantly, can I wait the DOM removal before changing routes?
Thank you for your time and help!
Edit 1
For a better understanding, my app.vue has a keep alive, so all the direct children (e.g. the lists of users, etc) do not send a request to the server every single time they are activated. The structure of the App.vue looks like this:
<template>
<keep-alive>
<router-view/>
</keep-alive>
</template>
Edit 2
In some further tests I discovered the workaround was not working in 100% of cases, so I changed the workaround to this:
async redirectToUser(userId) {
this.$router.push({name: 'Users'});
await this.$nextTick();
this.$router.push({
name: 'User',
params: {id: userId}
});
},
This way I first redirect the user to the parent component, so the life cycle of the child component is fully executed and its DOM elements removed, and then the user is redirected to the User component.
Working 100% of the time so far.
<router-view :key="$route.fullPath"></router-view>
. See What is <router-view :key=β$route.fullPathβ> ? β PhilUser
is children of componentUsers
. Can you add it inside it and check? β Varit J Patelthis.$router.push({name: 'User'});
β marceloatg