繁体   English   中英

如何从 Vue.js 功能组件发出事件?

[英]How to emit an event from Vue.js Functional component?

作为问题的标题, this上下文在功能组件中不可用。 所以如果我必须发出一个事件,我该怎么做呢?

例如在下面的代码片段中:

<template functional>
    <div>
        <some-child @change="$emit('change')"></some-child>
    </div>
</template>

我的功能组件没有this上下文,因此$emit不可用。 我怎样才能冒泡这个活​​动?

子组件

<template functional>
  <button @click="listeners['custom-event']('message from child')">
    Button from child
  </button>
</template>

父组件

<template>
  <div>
    <child-component @custom-event="call_a_method" />
  </div>
</template>

在代码沙箱上查看它的实际操作

你想从 vue 实例中发出事件吗?

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

另请参阅此处的沙盒示例

这在将属性和事件传递给子元素/组件的文档中进行了解释:

如果您使用基于模板的功能组件,您还必须手动添加属性和侦听器。 由于我们可以访问各个上下文内容,因此我们可以使用data.attrs传递任何 HTML 属性和listeners器( data.on的别名)来传递任何事件侦听器。

在最基本的层面上,您可以像这样委派所有侦听器:

<some-child v-on="listeners"></some-child>

如果您只想绑定change侦听器,您可以执行以下操作:

<some-child @change="listeners.change"></some-child>

但是如果listeners.change是 undefined/null (未提供给功能组件),这将失败。

如果您需要处理没有change侦听器的情况,那么您可以这样做:

<some-child @change="listeners.change && listeners.change($event)"></some-child>

否则您将不得不通过手动编写渲染函数来解决,因为我认为不可能有条件地将change侦听器分配给功能组件模板中的<some-child> (或者也许你可以?我不确定。)

如果您想有条件地传递事件侦听器,您可以在功能组件模板中执行此操作,如下所示:

v-on="listeners.change ? { change: listeners.change } : null"

这里讨论了有条件地附加侦听器的问题

带有 jsx 的组件:

export default {
  name: "MyText",
  functional: true,// functional component
  props: {
    value: {
      type: [String, Number],
      default: ""
    }
  },
  render(h, context) {
    const { props } = context;

    // with jsx

    // return (
    //   <button
    //     onClick={() => {
    //       console.log(context.listeners);
    //       context.listeners.input(Math.random().toString(36));
    //       context.listeners["my-change"](Math.random().toString(36));
    //       context.data.on.change(Math.random().toString(36));
    //     }}
    //   >
    //     {props.value}
    //   </button>
    // );

    // or use h function
    return h(
      "h1",
      {
        on: {
         // emit some event when click h1
          click: () => {
            // has value prop has has input event auto
            // event name come  what event u listen in parent component
            console.log(context.listeners);
            context.listeners.input(Math.random().toString(36));
            context.listeners["my-change"](Math.random().toString(36));
            context.data.on.change(Math.random().toString(36));
          }
        }
      },
      props.value
    );
  }
};

conext.listeners只是context.data.on的别名。 在父组件中,您应该听my-changechange ,否则有错误。

组件内的事件名称来自您在父组件中侦听的事件

<MyText
  v-model="value"
  @change="change"
  @my-change="myChange"
  @u-change="uChange"
/>

vue 2.6.11 运行良好。

在线查看代码框

家长:

<Child @onFunction="handleFunction">

这是子组件:

孩子

<template functional>
    <div>
        <some-child @change="execute"></some-child>
    </div>
</template>

methods:
  execute(){
   @emit("onFunction")
  }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM