如何在功能性 Vuejs 组件中发出事件

Posted

技术标签:

【中文标题】如何在功能性 Vuejs 组件中发出事件【英文标题】:How to emit events in a functional Vuejs component 【发布时间】:2017-11-02 21:36:01 【问题描述】:

我写了一个functional component 来编译特定条件的表单域。表单字段是它们自己的组件。所以我分为三个层次:

<FormComponent>          // handles input events
  <FunctionalComponent>  // selects form fields
    <FormFieldComponent> // emits input events
  </FunctionalComponent>
</FormComponent>

函数式组件没有this,但获取一个上下文对象作为渲染函数的参数。我能做的是使用context.data.on[eventName](event) 或一些类似的结构。我也知道我可以直接使用事件总线或 dom 元素,如 here 所述。

这一切在我看来都相当肮脏。 功能组件中是否有任何 this.$emit 等价物?

【问题讨论】:

您是说您希望您的 FunctionalComponent 将事件从您的 FormFieldComponent 冒泡到您的 FormComponent? github.com/vuejs/vue/issues/3348 是的,就是这样!我花了一分钟的时间来解决它,但这应该可以解决我的问题。非常感谢@RoyJ 【参考方案1】:

这是一个发出事件的功能组件的外观:

export default 
  functional: true,
  render(createElement,  listeners ) 
    return createElement(
      "button",
      
        on: 
          click: event => 
            const emit_event = listeners.event_from_child; //> the name is: event_from_child
            emit_event("Hello World!Is this the message we excpected? :/");
          
        
      ,
      "Pass event to parent"
    );
  
;

并监听父组件:

<functional-component @event_from_child="event_from_child"></functional-component>

在行动中看到它here

【讨论】:

【参考方案2】:

感谢@RoyJ 的评论,我能够解决我的问题。对于可能面临同样问题的每个人:

如github issue 中所述,render 函数的第二个参数有一个数据对象,其中包含所有侦听器等等。所以最简单的方法就是直接给子组件:

render(h, context) 
  return h(FormFieldComponent, context.data, children)

在我的具体情况下,我只直接获取侦听器,因为我操作了大部分数据对象:

render(h, context) 
  const data = createDataObject()
  data.on = context.data.on

  return h(FormFieldComponent, data, children)

【讨论】:

以上是关于如何在功能性 Vuejs 组件中发出事件的主要内容,如果未能解决你的问题,请参考以下文章

如何在反应js中发生事件(按钮单击)时将组件替换为另一个组件

如何在 vue 上使用 eventBus 触发点击事件?

如何根据父组件的点击事件打开添加模式-vuejs

如何在 vuejs 中隔离父元素和子元素之间的单击事件处理程序

vueJS3 - 如何触发来自兄弟组件的事件的函数

VueJS 功能组件(SFC):如何封装代码?