【问题标题】:Vue 3 defineEmits breaks defineProps typesVue 3 defineEmits 打破了 defineProps 类型
【发布时间】:2021-11-22 17:31:36
【问题描述】:

我正在使用 Vue 3 和 TS 4.4。我有一个用defineProps 定义其道具类型的组件。当我添加对defineEmits 的调用时,VS Code 开始告诉我我的props 变量在组件模板中不存在。这是源代码:

<script setup lang="ts">
import { defineProps, defineEmits, VueElement, defineComponent } from "vue";

const emit = defineEmits<{
  "update:checked": boolean;
}>();

const props = defineProps<{
  label?: VueElement | string;
  checked?: boolean;
}>();
</script>

<template>
  <label>
    <input
      type="checkbox"
      :checked="props.checked"
      @change="(event) => emit('update:checked', (event.target as any)?.checked)"
    />
    {{ props.label }}
  </label>
</template>

还有几个屏幕截图可以更好地展示我在 VS Code 中看到的内容。这是在添加defineEmits之后:

这是没有defineEmits

为 props 和 emits 定义类型的正确方法是什么?

【问题讨论】:

    标签: javascript typescript vue.js vuejs3


    【解决方案1】:

    defineEmits&lt;T&gt;() generic argument 本质上是一个 TypeScript 接口,它只定义了函数,它们接收特定的事件名称和可选参数:

    interface Emits {
      (e: __EVENT1_NAME__ [, arg1: __ARG1_TYPE__ [, arg2: __ARG2_TYPE__]]...): void
      (e: __EVENT2_NAME__ [, arg1: __ARG1_TYPE__ [, arg2: __ARG2_TYPE__]]...): void
    }
    

    例子:

    // as inline type
    const emits = defineEmits<{
      (eventName: 'hover', hovering: boolean): void
      (eventName: 'changed', newValue: number, id: string): void
    }>()
    
    // as interface
    interface Emits {
      (eventName: 'hover', hovering: boolean): void
      (eventName: 'changed', newValue: number, id: string): void
    }
    const emits = defineEmits<Emits>()
    
    // as type alias
    type Emits = {
      (eventName: 'hover', hovering: boolean): void
      (eventName: 'changed', newValue: number, id: string): void
    }
    const emits = defineEmits<Emits>()
    

    对于您的update:checked 事件,代码应类似于以下内容:

    // as inline type
    const emits = defineEmits<{
      (e: 'update:checked', checked: boolean): void
    }>()
    
    // as interface
    interface Emits {
      (e: 'update:checked', checked: boolean): void
    }
    const emits = defineEmits<Emits>()
    
    // as type alias
    type Emits = {
      (e: 'update:checked', checked: boolean): void
    }
    const emits = defineEmits<Emits>()
    

    【讨论】:

    • 不,您可以在同一个defineEmits() 调用中定义多个发射(如docs 所示)。如果在 VS Code 中使用 VueDX,请忽略模板中的错误(它似乎与 &lt;script setup&gt; 不完全兼容)。然而,模板中显示的ts 错误似乎是正确的。
    猜你喜欢
    • 2021-11-20
    • 2022-06-21
    • 2018-12-02
    • 2018-08-30
    • 2017-12-30
    • 2022-09-28
    • 2023-02-16
    • 2020-04-16
    • 2018-02-04
    相关资源
    最近更新 更多