withDefaults 是专为 defineProps 设计的编译时宏,用于 TypeScript 类型声明的 Props 设置默认值,需配合泛型类型使用,引用类型默认值必须用函数返回以避免共享。

在 <script setup> 中,withDefaults 是专为 defineProps 设计的编译时宏,用于给 TypeScript 类型声明的 Props 设置默认值。它不需导入,直接调用,且只在类型声明方式下生效。
必须配合 defineProps 的类型声明使用
withDefaults 不能和运行时声明(如 defineProps({ msg: String }))混用,否则会报错。它只接受泛型接口或内联类型作为第一个参数:
- 正确写法:用
<{ msg?: string; count?: number }>()这类类型标注 - 错误写法:同时写类型 + 运行时配置,比如
defineProps<...>({ msg: String })
基本语法结构清晰
格式固定为:
const props = withDefaults(defineProps<YourType>(), { /* 默认值对象 */ })例如:
立即学习“前端免费学习笔记(深入)”;
Vue 3 组合式 API 与 最佳实践,涵盖代码组织、useXxx 模式、组合式函数设计、Store 集成、响应式优化及功能抽取。
<script setup lang="ts">
interface Props {
title: string
count?: number
theme?: 'light' | 'dark'
}
const props = withDefaults(defineProps<Props>(), {
count: 0,
theme: 'light'
})
</script>这里 title 没设默认值,说明它是必传项;count 和 theme 有默认值,父组件不传时自动生效。
复杂类型要用函数返回避免引用污染
数组、对象等引用类型不能直接写字面量,默认值会被所有组件实例共享。必须用函数包裹:
- ✅ 推荐:
users: () => [{ id: 1, name: 'Alice' }] - ❌ 危险:
users: [{ id: 1, name: 'Alice' }](多个组件实例共用同一数组)
函数形式也支持简单计算逻辑,但注意:不能访问 setup 内部变量(如 ref 或其他 const),因为它是编译阶段执行的。
默认值仅在父组件未传递时生效
这个行为和 Vue 2 的 default 一致:
- 父组件写了
<MyComp title="Hi" />→ 使用传入的"Hi" - 父组件写了
<MyComp />→ 使用withDefaults里定义的默认值 - 父组件写了
<MyComp :title="undefined" />→ 依然使用默认值(undefined视为未传)
也就是说,只要属性没被显式赋予非 undefined 值,就走默认逻辑。

















