3

How can I set a default value of a nested property of a Object prop?

Apparently, Vue parse default value of nested properties only if the first level Object prop is undefined.

Example:

Vue.component('example', {
  props: {
    options: {
       type: Object,
       default: function() {
          return {
             nested: {
                type: Object,
                default: function(){
                   return 'default value'
                }
             }
          }
       }
    }
})

2 Answers 2

8

Apparently, Vue parse default value of nested properties only if the fist level Object prop is not undefined.

Yes and it makes sense because if you don't have outer object, you won't be able to have inner or nested properties.

So I think it's even more readable just set as default {} an emtpy object for the first level object and you should make your own defensive validations against undefined or null, like the bellow example:

<script>
  export default {
    props: {
      option: {
        type: Object,
        default: () => {},
        required: false
      }
    },
    computed: {
      optionReceived: function () {
        const defaultNestedValue = 'Some default value'
        const option = this.option.nested || defaultNestedValue;
        return option;
      }
    }
  }
</script>
Sign up to request clarification or add additional context in comments.

9 Comments

EDIT: Apparently, Vue parse default value of nested properties only if the first level Object prop is undefined. (sorry for the typo)
In my example, if the first level object is undefined: <example><example> The value of options.nested is set to default. But passing a partial option prop: let options = {} <example :options=options><example> The partial options object is not merged with default value of nested properties.
I managed to resolve this defining computed properties, that returns this.options.nested or the default value. But i'm not sure that's the best approach.
@DaniloSampaio usign computed properties is a good approach if the property change it's value on the parent it will update the property in the child component. Regarding why when you are passing an empty object {} to the component and is not setting the default value is because an empty object is a truthy value. Take a look to this developer.mozilla.org/en-US/docs/Glossary/Truthy
Is there any reason why Vue doesn't merge the passed object with the default value of the nested properties? Performance, simplicity, etc.
|
2

I think it is always better to make your data structure easy to use and as flat as possible. Because nested props in Vue is never a good choice.

Assume the options you mentioned in your Vue component have a lot of properties inside.

Example:

props: {
  options: {
    bookAttributes: {
      colorAttributes: { coverColor:   'red', ribbonColor: 'green' },
      sizeAttributes: { coverSize: 10, ribbonSize: 2 },
      ... 
    }
  }
}

you could make them flat like this for better comprehension.

props: {
    coverSize: 10,
    coverColor: 'red',
    ribbonColor: 'green,
    ribbonSize: 2 ...
}

And then you and your colleagues could happily use your component like this:

<your-component>
    coverSize="15"
    coverColor="blue"
    ribbonColor="red"
    ribbonSize="3"
</your-component>

Good luck and wish you well.

2 Comments

For a simple option object, it works fine. But when i have a complex component, a flat prop object might be too verbose: <your-component> childCompCoverSize="15" </your-component>
If your component is complex, simply break it down into small components. "Parent-Children" model should provide you convenience on passing props.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.