为什么第一次访问时未调用已激活的生命周期挂钩

时间:2019-03-01 09:02:13

标签: vuejs2 vue-router

我遇到一个问题,就是router-view中保持活动的组件在首次创建时不会调用其activated生命周期挂钩。 createdmounted生命周期挂钩正在被调用。第二次访问时,将调用activated钩子。

由于涉及到一些嵌套和插槽,因此情况非常复杂。

我试图创建一个最小的示例,您可以在下面找到它,或者在https://codesandbox.io/s/251k1pq9n上更详细一些。

不幸的是,它相当大,但还不如我不幸无法共享的真实代码那么复杂。

更糟糕的是,在最小的示例中,我未能重现实际的问题。在这里,createdmountedactivated生命周期挂钩在首次访问SlotExample时都被调用。

在我的真实代码中,第一次访问仅调用createdmounted生命周期钩子,随后的访问则调用activated钩子。有趣的是,所有生命周期挂钩都按SlotParent的预期进行调用。

真正的代码涉及更多的嵌套,并利用插槽来使用布局组件。

我的代码使用的是Vue 2.5.16和Vue-Router 3.0.1,但在Due 2.6.7和Vue-Router 3.0.2中也无法正常工作。我也在使用Vuetify和Vue-Head,但认为这与我的问题无关。

index.js。

有人知道我可能做错了什么吗?我实际上怀疑vue-router中的错误 当使用多个嵌套的插槽和keep-alive但无法复制时。

index.js

import Vue from "vue";
import VueRouter from "vue-router";
import App from "./App.vue";
import Start from "./Start.vue";
import SlotExample from "./SlotExample.vue";

const routes = [
    {
        path: "/start",
       component: Start
    },
    {
        path: "/slotExample/:id",
        component: SlotExample,
        props: true
    }
];

const router = new VueRouter({ routes });

Vue.use(VueRouter);

new Vue({
    render: h => h(App),
    router,
    components: { App }
}).$mount("#app");

App.vue

<template>
    <div id="app">
        <div>
            <keep-alive><router-view/></keep-alive>
        </div>
    </div>
</template>

SlotExample.vue

<template>
    <div>
        <h1>Slot Example</h1>
        <router-link to="/start"><a>start</a></router-link>
        <router-link to="/slotExample/123">
    <a>slotExample 123</a>
  </router-link>
        <slot-parent :id="id">
            <slot-child
                slot-scope="user"
                :firstName="user.firstName"
                :lastName="user.lastName"/>
        </slot-parent>
    </div>  
</template>

<script>
    import SlotParent from "./SlotParent.vue";
    import SlotChild from "./SlotChild.vue";
    export default {
        name: "slotExample",
        components: { SlotParent, SlotChild },
        props: {
            id: {
                type: String,
                required: true
            }
        }
    };
</script>

SlotParent.vue

<template>
    <div>
        <div slot="header"><h1>SlotParent</h1></div>
        <div slot="content-area">
            <slot :firstName="firstName" :lastName="lastName" />
        </div>
    </div>
</template>

<script>
    export default {
        name: "slotParent",
        props: {
            id: {
                type: String,
                required: true
            }
        },
        computed: {
            firstName() {
                if (this.id === "123") {
                    return "John";
                } else {
                    return "Jane";
                }
            },
            lastName() {
                return "Doe";
            }
        }
    };
</script>

SlotChild.vue

<template>
    <div>
        <h2>SlotChild</h2>
        <p>{{ firstName }} {{ lastName }}</p>
    </div>
</template>

<script>
    export default {
        name: "slotChild",
        props: {
            firstName: {
                type: String,
                required: true
            },
            lastName: {
                type: String,
                required: true
            }
        },
        created() {
            console.log("slotChild created");
        },
        mounted() {
            console.log("slotChild mounted");
        },
        activated() {
            console.log("slotChild activated");
        }
    };
</script>

1 个答案:

答案 0 :(得分:0)

我认为您需要将SlotChild放在keep-alive内。

看看vue js doc about activated hook