如何通过 Composition API 和 TSX 模板在 Vue 3 中使用自定义事件处理程序?

Ily*_*nov 6 vue.js tsx vuejs3 vue-composition-api

我正在努力理解如何使用 TSX 模板处理 Vue 3 中的自定义事件。

考虑一个简单的父/子应用程序,其中子级向父级发送自定义事件:

const Child = defineComponent({
    emits: {
        boom: (x: number) => true,
    },
    setup(props, { emit }) {
        console.log("Child props", props)
        return () => (
            <div onClick={() => emit("boom", 123)}>Click me!</div>
        )
    },
})

const Parent = defineComponent(() => {
    return () => <Child onBoom={(x) => console.log(`Boom: ${x}`)} />
})
Run Code Online (Sandbox Code Playgroud)

上述功能正常,并且:

  • 在 child 中setupprops是空的(正如我所期望的)。
  • emitchild 中的调用已正确键入(它需要传递一个数字作为参数)。

不幸的是,它不知道如何输入onBoom父级:

  Property 'onBoom' does not exist on type 'IntrinsicAttributes & Partial<{}> & Pick<Readonly<{} & {}> & VNodeProps & AllowedComponentProps & ComponentCustomProps, "style" | ... 8 more ... | "class">'.ts(2322)
Run Code Online (Sandbox Code Playgroud)

现在,如果我向 Child 添加onBoom属性定义:

const Child = defineComponent({
    props: {
        onBoom: Function as PropType<(x: string) => void>,
    },
    emits: {
        boom: (x: number) => true,
    },
    ...
Run Code Online (Sandbox Code Playgroud)

然后它仍然可以正常运行,并且onBoom在父级中被键入,但是:

  • 开发人员必须在两个地方重复事件定义。
  • 没有什么可以阻止这两个定义不同步。在上面的例子中,您是否注意到我输入的是错误的x: string而不是?x: numberprops.onBoom
  • 在 child 中setupprops现在不为空,它是一个具有onBoom属性的对象。

我的问题是:使用 Vue 3、Composition API 和 TSX 模板处理自定义事件的“正确”方法是什么?

老实说,我很想忽略整个emits/emit机制,而简单地使用 React 风格的回调:

<div onClick={() => props.onBoom?.("five")}>
Run Code Online (Sandbox Code Playgroud)

(目前阻止我的是,我知道当我决定使用 SSR 时它可能会破裂,因为这些特性不会水合。)

Eji*_*whu 0

在您的模板中,emit 选项全局可用,因此您可以执行此操作

<button @click="$emit('onBoom')">onBoom</button>
Run Code Online (Sandbox Code Playgroud)