ii iml0sto1
ii iml0sto1

Reputation: 1742

Vue3 Composition API with Typescript Default Values for nested objects not working as expected

I want to be able to set default values for nested datasets in Vue, basically, if a key does not have a value in the dataset that is being parsed to the component, I would like that value to be filled in automatically. This kinda works looking into this example here. However, my sample which is nested with several keys in the main object seems not to work. Why is that? what am I doing wrong?

Test Component

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

export type KitchenType = {
    windows: number;
};

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

const props = defineProps({
    dataset: {
        type: Object as PropType<DefaultTestType>,
        default: () => ({
            kitchen: {
                windows: 5,
            },
            rooms: 3,
        })
    },
});

console.log('IAM DATASET: ', props.dataset);
</script>

Calling the Component

<DefaultTest :dataset="{
    rooms: 5,
}" />

Console.log result

{ rooms: 5 }

Console.log expected result

{ kitchen: { windows: 5, }, rooms: 5 }

I'm using Laravel 9 with Vite, Inertia and Vue3 and have enabled the reactivityTransform: true in the vite.config file as told here through here

If I don't pass any dataset object, I am getting all the default values

Upvotes: 1

Views: 4983

Answers (3)

TrippleN
TrippleN

Reputation: 144

Have you ever tried withDefaults macro to define props with the default value

export interface Props {
  msg?: string
  labels?: string[]
}

const props = withDefaults(defineProps<Props>(), {
  msg: 'hello',
  labels: () => ['one', 'two']
})

Upvotes: 5

Fanoflix
Fanoflix

Reputation: 2089

Here is how to use withDefaults with a default object:


interface CustomStyles {
  padding: string
  margin: string
}
interface Props {
  message: string
  styles: CustomStyles
}

const props = withDefaults(defineProps<Props>(), {
  message: "test",
  customStyles: () => ({ 
    padding: "5px",
    margin: "4px"
  }) // notice the round brackets around the object
})

Upvotes: 1

TymoteuszLao
TymoteuszLao

Reputation: 954

I do not think it is possible to do such a thing with the use of default. Although you can create a default object then with the use of the Object.assign() method create a new object with default values, which will be overwritten by the prop you will receive.

const deafult = { kitchen: { windows: 5, }, rooms: 5 };

const recive = {rooms: 3}; //a prop

const mergedValues = Object.assign(deafult, recive);

console.log(mergedValues)

Upvotes: 1

Related Questions