我在vue.js中遇到一个一致的行为,找不到描述它的任何文档,我想知道的是这种行为是否可预期。
我正在使用vue.js 2.6.8,@ vue / cli-service 3.5.1和vue-router 3.0.1开发SPA。
我的路线如下:
{
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}
}
用户组件是用户列表,并在其中具有路由器视图,以呈现新的用户模式,如下所示:
<template>
<my-list-component>
<template #modal>
<router-view/>
</template>
</my-list-component>
</template>
在此组件内,用户可以单击按钮以推送新的路由 NewUserModal ,然后显示一个模式,在该模式下可以创建新用户,并且在操作完成后会进行另一次路由器推送,因此用户将被重定向到 User 路由。简而言之:
用户-> NewUserModal->用户
NewUserModal的所有阶段都发生了,确实被销毁了。但是,如果我返回到Users组件,NewUserModal的DOM元素仍然存在,因此我会看到父组件上被破坏的子组件的DOM。
我的印象是路由更改发生得“太快了”,并且在调用NewUserModal组件的destroy方法时,页面中不再存在需要销毁的DOM元素,因此无法将其删除。
>作为一种解决方法,我在NewUserModal中放置了以下代码:
beforeDestroy() {
this.$el.remove();
},
一切正常。那么,这是vue的预期行为吗?我想念什么吗?而且更重要的是,我可以在更改路由之前等待DOM删除吗?
感谢您的时间和帮助!
编辑1
为了更好地理解,我的app.vue保持活动状态,因此所有直接子级(例如,用户列表等)都不会在每次激活时都向服务器发送请求。 App.vue的结构如下:
<template>
<keep-alive>
<router-view/>
</keep-alive>
</template>
编辑2
在一些进一步的测试中,我发现此解决方法在100%的情况下均无效,因此我将解决方法更改为:
async redirectToUser(userId) {
this.$router.push({name: 'Users'});
await this.$nextTick();
this.$router.push({
name: 'User',
params: {id: userId}
});
},
通过这种方式,我首先将用户重定向到父组件,因此将完全执行子组件的生命周期并删除其DOM元素,然后将用户重定向到User组件。
到目前为止,有100%的时间在工作。
答案 0 :(得分:0)
因此,当您路由到user/:id
时,组件实例将被重用。
对于任何id
-(根据文档)。
也许Navigation Guards能帮上忙吗?
例如:
beforeRouteUpdate (to, from, next) {
// called when the route that renders this component has changed,
// but this component is reused in the new route.
// For example, for a route with dynamic params `/foo/:id`, when we
// navigate between `/foo/1` and `/foo/2`, the same `Foo` component instance
// will be reused, and this hook will be called when that happens.
// has access to `this` component instance.
},
更重要的是,我可以在更改路由之前等待DOM删除吗?
async beforeRouteLeave (to, from, next) {
// called when the route that renders this component is about to
// be navigated away from.
// has access to `this` component instance.
// maybe wait for next render
await this.nextTick();
next()
}