Vue.js-在更改路线后未从父组件中删除DOM元素

时间:2019-03-15 04:42:09

标签: dom vue.js vue-router vue-cli-3

我在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%的时间在工作。

1 个答案:

答案 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()
  }