前言
Vue3 的 Composition API 让开发者能够更灵活地组织逻辑,但很多人在使用 defineProps 时,还停留在 Vue2 的思维模式。这篇文章将带你了解如何正确使用 defineProps,写出专业、高效的 Vue3 组件。
一、defineProps 的三种正确写法
(一)声明式类型推导(推荐)
这是 TypeScript 驱动的写法,无需运行时校验:
interface Props {
title: string;
count?: number;
}
const props = defineProps<Props>();
这种方式能自动获得类型推导,与 withDefaults 配合还可补充默认值。
(二)运行时代码校验(Options 式)
适合 JS 项目:
const props = defineProps({
title: {
type: String,
required: true
},
count: {
type: Number,
default: 0
}
});
保留 Vue2 的校验逻辑,但类型推导不如泛型直观。
(三)与 withDefaults 配合
这是实战中最常见的写法:
const props = withDefaults(defineProps<{
title?: string;
count?: number;
}>(), {
title: '默认标题',
count: 1
});
既获得类型推导,又可写默认值,简洁易维护。
二、高发误区及解决方法
(一)直接解构导致响应性丢失
错误写法:
const { title, count } = defineProps<{ title: string; count: number }>();
应改为使用 toRefs:
const props = defineProps<{ title: string; count: number }>();
const { title, count } = toRefs(props);
这样可确保响应性。
(二)类型和默认值重复声明
在 TS 项目中,避免以下写法:
const props = defineProps({
title: {
type: String as PropType<string>,
default: 'Hello'
}
});
建议用泛型 + withDefaults,让 IDE 自动推导类型。
(三)未区分开发期类型检查与运行时校验
Vue3 的 Props 有 TypeScript 模式和 Options 模式。推荐生产环境靠 TypeScript 检查,提高性能。
三、defineProps 的进阶技巧
(一)使用类型别名
type Size = 'sm' | 'md' | 'lg';
withDefaults(defineProps<{
size?: Size;
}>(), {
size: 'md'
});
可让 props.size 具备完整类型提示。
(二)配合 defineEmits
const emit = defineEmits<{
(e: 'submit', value: number): void;
(e: 'cancel'): void;
}>();
让组件的输入输出都具备契约,便于 IDE 识别。
(三)确保类型推导
正确写法能让 IDE 在 <MyComponent :title="xx" /> 中提供类型提示。保持结构清晰是关键。
四、总结
- • 避免不加泛型、直接解构、类型+default 双声明等错误。
- • 推荐采用
defineProps<T>() + withDefaults()写法。
正确的组件开发应做到:
- • 使用泛型 +
withDefaults - • 保持 props 和 emits 的契约完整
- • 清晰的类型提示和响应性解构