withdefaults 用于 中为 props 设置默认值,基本类型可直接赋值,对象数组等引用类型必须用工厂函数避免共享引用,且默认值须严格匹配类型声明。

Vue 3 中用 withDefaults 设置 Props 默认值,核心是“类型声明 + 默认值注入”,它必须配合 defineProps 在 <script setup></script> 中使用,不能用于选项式 API。关键不是写对语法,而是写对类型和默认值的匹配方式——尤其对象、数组这类引用类型,必须用工厂函数避免共享引用。
基础写法:字符串/数字等基本类型直接写
如果默认值是简单值(如字符串、布尔、数字),可直接在 withDefaults 的第二个参数里赋值:
const props = withDefaults(defineProps(), { title: '默认标题', size: 14 });- 此时
title和size在父组件没传时,自动取对应默认值,TS 类型推导完全准确,模板中可直接用{{ props.title }}不报错。
安全写法:对象/数组必须用箭头函数返回新实例
对 object、array、function 等引用类型,绝不能写 { config: {} } 或 { list: [] } —— 否则所有组件实例会共用同一份内存,导致状态污染:
- ✅ 正确:
config: () => ({ theme: 'light', delay: 300 }) - ✅ 正确:
items: () => [{ id: 1, name: '默认项' }] - ❌ 错误:
config: { theme: 'light' }(所有实例共享该对象)
类型对齐要点:默认值必须严格匹配 Prop 声明类型
TS 会校验默认值是否符合泛型中定义的类型。常见报错原因:
- 声明了
status?: 'active' | 'inactive',但默认值写了'pending'→ 类型不兼容 - 声明了
data: Ref<string></string>,却给默认值'hello'→ 类型层级错位 - 解决方法:检查泛型定义与默认值字面量是否完全一致,必要时加类型断言或调整接口定义
注意边界:withDefaults 不改变 prop 的可选性
withDefaults 只提供默认值,并不把可选属性(?)变成必填。例如:
-
defineProps()+withDefaults(..., { name: '匿名' })→ 模板中props.name仍是可选类型,需用props.name ?? '备用'或确保 TS 非空断言合理 - 若希望强制非空,应在类型定义中去掉
?,比如name: string,再配默认值
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










