返回

Vue 3中的TSX自定义组件事件监听的正确方式

前端

引言

Vue 3是一个强大的前端框架,它允许开发者使用TypeScript(TS)来编写组件。TS是一种静态类型语言,可以帮助开发者在编码时发现错误,并提高代码的可读性和可维护性。然而,在使用TSX(TSX是TypeScript的JSX语法扩展)编写自定义组件时,监听组件事件可能会遇到类型错误。

问题

在Vue 3中,自定义组件的事件监听器通常使用@符号和事件名称来定义。例如,以下代码演示了如何在自定义组件中监听click事件:

import { defineComponent } from 'vue';

const MyComponent = defineComponent({
  template: `<button @click="handleClick">Click me</button>`,
  methods: {
    handleClick() {
      console.log('Button clicked!');
    },
  },
});

当编译这段代码时,可能会遇到以下类型错误:

error TS2322: Type '"click"' is not assignable to type '"pointerdown" | "pointerup" | "pointermove" | "pointerover" | "pointerout" | "pointercancel" | "pointerenter" | "pointerleave"'.

原因

这个问题的原因在于,在Vue 3中,自定义组件的事件监听器默认使用pointerdown事件。这是因为pointerdown事件是所有鼠标和触摸事件的共同祖先事件。当组件收到pointerdown事件时,它会触发所有与之关联的事件监听器。

然而,在上面的代码中,我们使用了@click事件监听器。这会导致类型错误,因为click事件并不是pointerdown事件的子事件。

解决方案

解决这个问题有两种方法。第一种方法是使用v-on指令来显式地绑定事件监听器。例如,以下代码演示了如何使用v-on指令来绑定click事件监听器:

import { defineComponent } from 'vue';

const MyComponent = defineComponent({
  template: `<button v-on:click="handleClick">Click me</button>`,
  methods: {
    handleClick() {
      console.log('Button clicked!');
    },
  },
});

使用v-on指令可以避免类型错误,因为v-on指令会自动将事件名称转换为正确的类型。

第二种方法是使用@native修饰符来告诉Vue 3,要使用原生的事件监听器。例如,以下代码演示了如何使用@native修饰符来绑定click事件监听器:

import { defineComponent } from 'vue';

const MyComponent = defineComponent({
  template: `<button @native.click="handleClick">Click me</button>`,
  methods: {
    handleClick() {
      console.log('Button clicked!');
    },
  },
});

使用@native修饰符也可以避免类型错误,因为@native修饰符会告诉Vue 3,要使用原生的事件监听器,而不是使用pointerdown事件。

总结

在Vue 3中,自定义组件的事件监听器默认使用pointerdown事件。这会导致类型错误,因为click事件并不是pointerdown事件的子事件。解决这个问题有两种方法。第一种方法是使用v-on指令来显式地绑定事件监听器。第二种方法是使用@native修饰符来告诉Vue 3,要使用原生的事件监听器。