标准答案

  1. props 类型要表达必填、可选、默认值和受控状态,避免把所有字段都写成 any 或过宽的 object。
  2. emits 类型要声明事件名和参数,保证父组件监听时能得到正确的参数提示。
  3. slots 类型要描述插槽可用的上下文,例如 row、index、selected、close 等,方便调用方写出类型安全的插槽内容。
  4. 泛型组件适合表格、列表、选择器、表单项等需要根据数据类型推导字段和回调参数的场景。
  5. 类型设计要服务组件使用者,不要为了展示复杂类型而牺牲调用体验。

题目解析

这道题可以按 props、emits、slots、generic 四个面向回答,每个面向都对应一个组件边界。

Vue 3 的 script setup 提供 defineProps、defineEmits、defineSlots 和 generic 属性,使组件契约更容易写在组件内部。

对于组件库或通用组件,类型越清晰,使用者越不容易传错字段、漏处理事件或误解插槽上下文。

代码示例

下面是一个简化的泛型列表组件类型示例。

Vue
<script setup lang="ts" generic="T extends { id: string | number }">
defineProps<{
  items: T[]
  selectedId?: T['id']
}>()

defineEmits<{
  select: [item: T]
}>()

defineSlots<{
  default(props: { item: T; selected: boolean }): unknown
}>()
</script>

常见误区

  • props、emits、slots 全部用 any,组件看似灵活,实际调用方没有类型保护。
  • 默认值和可选类型不一致,导致运行时有值但类型仍然提示可能 undefined。
  • 为了泛型而泛型,简单业务组件写出复杂到难以维护的类型。

作者信息