$emit 不会触发子事件
Posted
技术标签:
【中文标题】$emit 不会触发子事件【英文标题】:$emit doesn't trigger child events 【发布时间】:2017-03-30 22:56:17 【问题描述】:对于 VueJS 2.0 项目,我在父组件上有以下内容
<template>
<child></child>
<button @click="$emit('childEvent)"></button>
</template>
在我拥有的子组件上:
events: 'childEvent' : function().... ,
ready() this.$on('childEvent',...) ,
methods: childEvent() ....
点击按钮似乎没有任何效果。我是否需要创建一个父方法,然后将其发送给孩子?我使用的是 vuejs 1。但现在我对父子通信的工作方式感到困惑
【问题讨论】:
【参考方案1】:虽然其他答案是正确的,但通常可以使用数据驱动的方法。
我将为正在寻找这个问题的答案但需要除道具以外的其他方法的任何人添加此内容。在尝试将焦点设置在自定义表单组件中的特定输入上时,我遇到了类似的问题。为此,我必须给自定义组件一个 ref 然后执行此操作。
this.$refs.customInput.$emit('focus');
//or
this.$refs.customInput.directlyCallMethod();
这会访问孩子的 vue 实例,然后您可以发出该组件听到的事件。
【讨论】:
这看起来是个不错的解决方案。我认为这不应该成为标准做法。 @Teddy 不是Flux,这是 Vue 和 React 都推荐的状态管理架构。滥用它可能会导致回调意大利面。【参考方案2】:和documentation一样:
在 Vue.js 中,父子组件的关系可以概括为 props down,events up。父级通过 props 向下传递数据给子级,子级通过事件向父级发送消息。让我们看看它们接下来是如何工作的。
所以在最新的 Vue 中,您不能从父级向子级发送事件,您可以将道具传递给子级,并从子级向父级发送事件。
【讨论】:
您仍然可以使用 $root 在vue.js2
中将事件从父级发送到子级,但不建议这样做。【参考方案3】:
您可以为此使用自定义 Vue 实例。
// Globally
const eventBus = new Vue()
// In your child
eventBus.$on('eventName', () =>
// Do something
);
// In your parent
eventBus.$emit('eventName')
【讨论】:
这可行,我肯定在其他情况下使用过总线方法(当组件并排放置,而不是父子关系时),但污染全局命名空间往往是一件坏事想法,尤其是在使用 vanilla JS 时。【参考方案4】:从父到子的事件在 Vue 1.0 中使用 $broadcast()
完成,而在 Vue 2.0 中根本不可能。
您可能不需要它,通常有比不需要事件更好的解决方案,但这取决于您的用例。
【讨论】:
哇。这个家伙 Linus Borg 就像是 Vue 的核心贡献者。他应该知道他在说什么:D 我认为第一条评论是指最初在我的答案中出现的胡言乱语,这是因为我的手机自动更正变得疯狂,而我自己懒得在提交之前重新阅读我写的内容.;) 我在那条评论之后立即对其进行了编辑。【参考方案5】:我需要为可能存在多个并且每个道具都不合适的弹出框执行此操作。
要调度全局事件,可以将事件侦听器添加到 $root Vue 实例。
// Child:
created()
this.$root.$on('popover', (e) =>
// Determine if popover should close, etc.
this.close()
)
,
// Parent:
this.$emit('popover', 'arg1', 'argn')
记得在destroyed
中也调用$off。
【讨论】:
以上是关于$emit 不会触发子事件的主要内容,如果未能解决你的问题,请参考以下文章