Возникла проблема, когда пользовательское событие (swap-components
), генерируемое динамическим компонентом (A.vue
или B.vue
), неправильно прослушивается в родительском компоненте динамического компонента (HelloWorld.vue
).
Вот источник на GitHub (созданный с помощью vue cli 3).
Вот демоверсия live, показывающая проблему .
В демонстрационной версии вы увидите, что нажатие кнопки в динамическом компоненте с цветом фона НЕ изменяет динамический компонент.Но при нажатии кнопки под цветом фона (который начинается с родительского элемента HelloWorld.vue
), динамический компонент не изменяется.
Почему это происходит и как это исправить?
Ниже я скопирую содержимое 3 основных файлов, представляющих интерес, в этот пост:
HelloWorld.vue
(родитель)
A.vue
(подкомпонент, используемый в динамическом компоненте)
B.vue
(подкомпонент, используемый в динамическом компоненте)
HelloWorld.vue
:
<template>
<div>
<h1>The dynamic components ⤵️</h1>
<component
:is="current"
v-bind="dynamicProps"
></component>
<button
@click="click"
>Click me to swap components from within the parent of the dynamic component</button>
</div>
</template>
<script>
import A from "./A.vue";
import B from "./B.vue";
export default {
data() {
return {
current: "A"
};
},
computed: {
dynamicProps() {
return this.current === "A" ? { data: 11 } : { color: "black" };
}
},
methods: {
click() {
this.$emit("swap-components");
},
swapComponents() {
this.current = this.current === "A" ? "B" : "A";
}
},
mounted() {
this.$nextTick(() => {
// Code that will run only after the
// entire view has been rendered
this.$on("swap-components", this.swapComponents);
});
},
components: {
A,
B
},
props: {
msg: String
}
};
</script>
A.vue
:
<template>
<section id="A">
<h1>Component A</h1>
<p>Data prop sent from parent: "{{ data }}"</p>
<button @click="click">Click me to swap components from within the dynamic component</button>
</section>
</template>
<script>
export default {
props: ["data"],
methods: {
click() {
this.$emit("swap-components");
}
}
};
</script>
B.vue
:
<template>
<section id="B">
<h1>Component B</h1>
<p>Color prop sent from parent: "{{ color }}"</p>
<button @click="click">Click me to swap components from within the dynamic component</button>
</section>
</template>
<script>
export default {
props: ["color"],
methods: {
click() {
this.$emit("swap-components");
}
}
};
</script>