当事件从动态组件 child 发出时,Vue `vm.$on()` 回调在 parent 中不起作用
Vue `vm.$on()` callback not working in parent when event is emitted from dynamic component child
我遇到一个问题,动态组件(A.vue
或 B.vue
)发出的自定义事件(swap-components
)在 parent 的动态组件 (HelloWorld.vue
).
这里是 source on GitHub(使用 vue cli 3 创建)。
这里是live demo showing the problem.
在现场演示中,您会看到单击具有背景色的动态组件中的按钮不会更改动态组件。但是当单击背景颜色下方的按钮时(源自 HelloWorld.vue
parent),动态组件确实发生了变化。
为什么会发生这种情况以及如何解决?
下面我将把感兴趣的 3 个主要文件的内容复制到这个 post:
HelloWorld.vue
(parent)
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>
当您使用函数时,this
不再绑定到上下文。仅限于功能范围。使用箭头函数让this
绑定到父上下文。
变化:
this.$nextTick(function() {
与:
this.$nextTick(() => {
我猜这是因为事件侦听器正在侦听父组件本身发出的 swap-components
事件。也许您可以通过从子组件侦听 swap-components
事件然后在父组件上发出事件来解决此问题。
<template>
<div>
<h1>The dynamic components ⤵️</h1>
<component
:is="current"
v-bind="dynamicProps"
@swap-components="$emit('swap-components')"
></component>
<button
@click="click"
>Click me to swap components from within the parent of the dynamic component</button>
</div>
</template>
或者你可以在子组件发出事件时直接调用你的方法..
<template>
<div>
<h1>The dynamic components ⤵️</h1>
<component
:is="current"
v-bind="dynamicProps"
@swap-components="swapComponents"
></component>
<button
@click="click"
>Click me to swap components from within the parent of the dynamic component</button>
</div>
</template>
我遇到一个问题,动态组件(A.vue
或 B.vue
)发出的自定义事件(swap-components
)在 parent 的动态组件 (HelloWorld.vue
).
这里是 source on GitHub(使用 vue cli 3 创建)。
这里是live demo showing the problem.
在现场演示中,您会看到单击具有背景色的动态组件中的按钮不会更改动态组件。但是当单击背景颜色下方的按钮时(源自 HelloWorld.vue
parent),动态组件确实发生了变化。
为什么会发生这种情况以及如何解决?
下面我将把感兴趣的 3 个主要文件的内容复制到这个 post:
HelloWorld.vue
(parent)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>
this
不再绑定到上下文。仅限于功能范围。使用箭头函数让this
绑定到父上下文。
变化:
this.$nextTick(function() {
与:
this.$nextTick(() => {
我猜这是因为事件侦听器正在侦听父组件本身发出的 swap-components
事件。也许您可以通过从子组件侦听 swap-components
事件然后在父组件上发出事件来解决此问题。
<template>
<div>
<h1>The dynamic components ⤵️</h1>
<component
:is="current"
v-bind="dynamicProps"
@swap-components="$emit('swap-components')"
></component>
<button
@click="click"
>Click me to swap components from within the parent of the dynamic component</button>
</div>
</template>
或者你可以在子组件发出事件时直接调用你的方法..
<template>
<div>
<h1>The dynamic components ⤵️</h1>
<component
:is="current"
v-bind="dynamicProps"
@swap-components="swapComponents"
></component>
<button
@click="click"
>Click me to swap components from within the parent of the dynamic component</button>
</div>
</template>