碧优蒂的世界免费版
417.53MB · 2025-09-17
点赞 + 收藏 === 学会???
Vue 3 的
Composition API
给开发者带来了更强的逻辑组织能力,但很多人用defineProps
的方式,依然停留在 Vue 2 的“Options 语法心智”。本质上只是把props: {}
拿出来“提前声明”,并没有真正理解它的运行机制、类型推导优势、默认值处理方式、解构陷阱等关键点。这篇文章不做语法搬运,而是用实战视角,带你了解:defineProps 到底该怎么写,才是专业的 Vue3 写法。
我们先来看一个常见的 Vue3 组件写法:
<script setup>const props = defineProps({ title: String, count: Number})</script>
你以为这就完事了?它只是基本写法。但在真实业务中,我们往往会遇到:
这些问题,defineProps 其实早就帮你解决了,只是你没用对方式。
interface Props { title: string count?: number}const props = defineProps<Props>()
优点:
<script setup lang="ts">
中书写自然withDefaults
补充默认值这是 Composition API 的推荐写法,完全由 TypeScript 驱动,而不是运行时校验。
const props = defineProps({ title: { type: String, required: true }, count: { type: Number, default: 0 }})
优点:
缺点:
withDefaults
不兼容withDefaults
配合(实战最常见)const props = withDefaults(defineProps<{ title?: string count?: number}>(), { title: '默认标题', count: 1})
优势是:
注意:withDefaults 只能配合泛型式 defineProps 使用,不能和对象式 props 写法混用。
const { title, count } = defineProps<{ title: string, count: number }>()
上面的写法会让 title
和 count
成为普通变量,不是响应式的。
解决方式:使用 toRefs
const props = defineProps<{ title: string, count: number }>()const { title, count } = toRefs(props)
这样才能在 watch(title, ...)
中有效监听变化。
const props = defineProps({ title: { type: String as PropType<string>, // 写了类型 default: 'Hello' // 又写默认值 }})
在 TS 项目中,这种方式显得繁琐且不智能。建议直接用泛型 + withDefaults,让 IDE 自动推导类型。
Vue3 的 Props 有两个模式:
实际推荐:生产环境靠 TypeScript 检查即可,无需运行时 Props 校验,提高性能。
在 Vue3 的 <script setup>
中,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}>()
这样写出的组件,输入(props)+ 输出(emit)都具备契约,可以被任何 IDE 精确识别。
很多人发现 <MyComponent :title="xx" />
里没有类型提示,大概率是你组件没有正确写 defineProps 的泛型。保持结构清晰,是让 IDE 吃得饱的唯一方式。
正确思路是:在 TypeScript 项目中,尽可能采用 defineProps<T>() + withDefaults()
写法,做到类型明确、默认值清晰、响应式安全。
✅ 如果你能做到:
withDefaults
那恭喜你,是真的理解了 Vue3 的组件心智模型。