【发布时间】:2019-08-06 02:59:00
【问题描述】:
我在 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}
}
Users 组件是一个用户列表,内部有一个路由器视图,用于呈现新的用户模式,如下所示:
<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% 的时间都在工作。
【问题讨论】:
-
“但是,如果我回到用户组件” ????你怎么“回去”?
-
您可以尝试更改为
<router-view :key="$route.fullPath"></router-view>。见What is <router-view :key=“$route.fullPath”> ? -
显然,组件
User是组件Users的子组件。可以加进去看看吗? -
@Phil 所有的路由变化都是通过推送发生的,例如:
this.$router.push({name: 'User'}); -
@varit05 我可能错了,但事实并非如此。组件用户是用户列表,组件用户是单个用户的详细信息。 User 不是子路由,因为它不依赖于 Users 组件,它实际上是一个完全不同的页面。如果我将用户添加为用户的子路由,我将不得不处理用户列表,这不应该显示。
标签: dom vue.js vue-router vue-cli-3