标准答案
- props 类型要表达必填、可选、默认值和受控状态,避免把所有字段都写成 any 或过宽的 object。
- emits 类型要声明事件名和参数,保证父组件监听时能得到正确的参数提示。
- slots 类型要描述插槽可用的上下文,例如 row、index、selected、close 等,方便调用方写出类型安全的插槽内容。
- 泛型组件适合表格、列表、选择器、表单项等需要根据数据类型推导字段和回调参数的场景。
- 类型设计要服务组件使用者,不要为了展示复杂类型而牺牲调用体验。
题目解析
这道题可以按 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。
- 为了泛型而泛型,简单业务组件写出复杂到难以维护的类型。