vue 3 中需用 withdefaults 包裹 defineprops 设置 props 默认值,支持静态值与函数形式默认值,函数内不可访问 props;默认值键名须与类型定义严格一致,且推荐搭配 typescript 使用以保障类型安全。

在 Vue 3 的 Composition API 中,setup 函数本身不直接支持设置 props 默认值,但可以通过 defineProps 配合 withDefaults 实现类型安全且语义清晰的默认值声明。
使用 withDefaults 包裹 defineProps
withDefaults 是一个高阶函数,接收两个参数:一个是 defineProps 的类型定义(通常为对象或泛型),另一个是包含默认值的对象。它返回一个增强后的 props 响应式对象,其中未传入的 prop 会自动使用指定默认值。
注意:必须配合 defineProps 使用,不能单独调用;且默认值对象的键必须与 props 类型定义中的一致。
- 基础写法(运行时 + 类型推导):
const props = withDefaults(
defineProps title: string;
count?: number;
isActive?: boolean;
}>(),
{
count: 0,
isActive: true
}
);
```
此时 props.title 仍为必填项(无默认值),而 props.count 和 props.isActive 即使父组件没传,也会有默认值,且 TypeScript 能正确推导其非 undefined 类型。
默认值支持函数和响应式逻辑
默认值可以是静态值,也可以是返回值的函数(每次组件实例化时执行一次),适合需要动态初始化的场景,比如生成唯一 ID、获取当前时间等。
- 函数形式默认值(避免引用共享):
const props = withDefaults(
defineProps id?: string;
createdAt?: Date;
}>(),
{
id: () => Math.random().toString(36).slice(2, 10),
createdAt: () => new Date()
}
);
```
⚠️ 注意:不能在函数中访问 props 或其他响应式数据(如 ref),因为此时 props 尚未创建完成。
与 defineProps 类型声明的兼容性
如果你使用的是纯运行时声明(无 TypeScript),也可以用对象形式,但会丢失类型提示:
```jsconst props = withDefaults(
defineProps(['title', 'count', 'isActive']),
{
count: 0,
isActive: false
}
);
```
不过强烈建议搭配 TypeScript 使用,以获得完整的类型检查和 IDE 支持。此时 count 和 isActive 在类型层面不再是可选(?),而是被确定为非 undefined。
常见误区提醒
- 不能在
setup()内部再调用withDefaults—— 它只能用于defineProps的返回值,且必须顶层调用; - 默认值对象中的 key 必须严格匹配 props 类型定义的 key,拼写错误会导致 TS 报错或默认值失效;
- 如果某 prop 是必填(无
?),又在withDefaults中设了默认值,TypeScript 会允许,但语义上矛盾,不推荐; -
withDefaults不影响父组件传入的值,只对未传的 prop 生效。










