You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3 Composition API+TS嵌套对象Props默认值未按预期生效

问题根本原因

Vue对prop默认值的处理是浅层级的全量替换逻辑,不会做深度属性合并,规则非常明确:

  • 只有当父组件完全不传递对应prop时,才会执行default工厂函数返回预设的默认值
  • 只要父组件传了该prop(哪怕传的对象只包含部分属性、缺了很多嵌套字段),Vue会直接使用传入的整个对象作为prop值,完全不会拿default里的对象和传入对象做任何层级的属性补全合并。

你当前的用例里父组件传了:dataset="{rooms: 5}",已经给dataset传了有效值,Vue就直接使用这个传入对象,不会补上default里预设的kitchen字段,所以控制台输出只有{rooms:5}。只有你完全省略:dataset传参时,才会触发default返回完整的默认对象,和你观察到的现象完全吻合。

代码实现的错误

你对Vue Object类型prop的默认值生效逻辑存在误解,写的default函数只覆盖了「dataset prop完全缺失」的场景,没有处理「dataset传了但内部属性/嵌套属性缺失」的补全场景,误以为Vue会自动递归合并嵌套对象的默认值,实际上Vue原生没有这个能力。

修复方法

根据你的嵌套层级选实现方式即可,两层结构直接手动合并最稳妥,避免引入额外的深合并依赖:

方式1:通过computed生成合并后的完整值(推荐,响应式稳定)

把默认值抽成独立常量,在组件内通过计算属性把传入值和默认值做合并,所有用到dataset的地方用这个计算属性即可:

<script setup lang="ts">
import { defineProps, PropType, computed } from 'vue';

export type KitchenType = {
    windows: number;
};

export type DefaultTestType = {
    kitchen?: KitchenType;
    rooms?: number;
};

// 抽离默认值
const getDefaultDataset = (): DefaultTestType => ({
    kitchen: {
        windows: 5,
    },
    rooms: 3,
})

const props = defineProps({
    dataset: {
        type: Object as PropType<DefaultTestType>,
        default: getDefaultDataset
    },
});

// 手动合并默认值和传入值
const mergedDataset = computed(() => {
    const defaultVal = getDefaultDataset()
    return {
        ...defaultVal,
        ...props.dataset,
        kitchen: {
            ...defaultVal.kitchen,
            ...props.dataset?.kitchen
        }
    }
})

console.log('IAM DATASET: ', mergedDataset.value);
</script>

方式2:在default函数内做合并(不需要额外计算属性)

default函数可以接收到父组件传入的原始prop值作为参数,直接在default内部完成合并返回即可,注意不要直接修改原始传入对象:

const props = defineProps({
    dataset: {
        type: Object as PropType<DefaultTestType>,
        default: (rawVal?: DefaultTestType): DefaultTestType => {
            const base = {
                kitchen: { windows:5 },
                rooms:3
            }
            if (!rawVal) return base
            return {
                ...base,
                ...rawVal,
                kitchen: {
                    ...base.kitchen,
                    ...rawVal.kitchen
                }
            }
        }
    }
})

如果你的数据嵌套层级超过3层,可以自己实现一个简单的深度合并函数替换上面的手动展开逻辑,Vue 3.3+版本也可以直接使用内置的mergeDeep工具函数完成深合并。


内容的提问来源于stack exchange,提问作者ii iml0sto1

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 18:57:26