Properties, where the value is an object, can be especially tricky. If you change an attribute in that object, the state is not changed. Thus, the child component doesn't get updated.
Check this example:
// ParentComponent.vue
<template>
<div>
<child-component :some-prop="anObject" />
<button type="button" @click="setObjectAttribute">Click me</button>
</div>
</template>
<script>
export default {
data() {
return {
anObject: {},
};
},
methods: {
setObjectAttribute() {
this.anObject.attribute = 'someValue';
},
},
};
</script>
// ChildComponent.vue
<template>
<div>
<strong>Attribute value is:</strong>
{{ someProp.attribute ? someProp.attribute : '(empty)' }}
</div>
</template>
<script>
export default {
props: [
'someProp',
],
};
</script>
When the user clicks on the "Click me" button, the local object is updated. However, since the object itself is the same -- only its attribute was changed -- a state change is not dispatched.
To fix that, the setObjectAttribute could be changed this way:
setObjectAttribute() {
// using ES6's spread operator
this.anObject = { ...this.anObject, attribute: 'someValue' };
// -- OR --
// using Object.assign
this.anObject = Object.assign({}, this.anObject, { attribute: 'someValue' });
}
By doing this, the anObject data attribute is receiving a new object reference. Then, the state is changed and the child component will receive that event.