必须用工厂函数,因为object和array是引用类型,直接赋字面量默认值会导致所有组件实例共享同一内存地址,引发状态污染;正确写法为default: () => []或default: () => ({})。

Vue 中为 Array 或 Object 类型的 props 设置默认值时,不能直接使用字面量(如 [] 或 {})作为默认值,否则所有组件实例会共享同一个引用,导致状态污染。必须用工厂函数(factory function)返回新对象或数组。
为什么必须用工厂函数?
因为 JavaScript 中对象和数组是引用类型。如果写成:
props: { list: { type: Array, default: [] } }这个空数组 [] 在组件定义时就被创建一次,所有该组件的实例都指向同一内存地址。一个实例修改了 list,其他实例也会受影响。
正确写法:工厂函数返回新实例
工厂函数必须是一个函数,且不带参数(Vue 会自动调用它),每次调用都返回全新的对象或数组:
-
数组默认值:
default: () => [] -
对象默认值:
default: () => ({}) -
带初始内容的对象:
default: () => ({ name: '', count: 0 }) -
带初始内容的数组:
default: () => [{ id: 1, text: '默认项' }]
TypeScript 中的注意事项
在 TS + Vue 3 的组合式 API(defineProps)中,工厂函数写法不变,但需确保类型推导正确:
items: { type: Array as PropType
config: { type: Object as PropType, default: () => ({ theme: 'light' }) }
}
注意:必须用 as PropType<...></...> 显式标注类型,否则 default 函数返回值可能无法被正确推导。
常见错误写法(务必避免)
-
default: []❌ —— 直接字面量,共享引用 -
default: function() { return this.someData }❌ —— 工厂函数内访问this,此时this尚未初始化,会报错或返回undefined -
default: () => this.options❌ —— 同上,props 初始化早于组件实例创建










