Reputation: 437
I want a child component to reload everytime the object, which i transfer to the child as a prop, changes. I read that VueJs can not detect a change in an Object. So far so good, I came up with the following Idea:
Everytime my Object changes, I perform a change in a normal variable which I also transfer via a prop to the child. My idea was it to "force" a rerendering of the child component through the change of the normal variable. But it seems not to work and I don't understand why it doesn't work.
Parent File:
<template>
<compare-value :ocean="ocean" :update="updateComponent" v-if="ocean.length > 0"></compare-value>
</template>
<script>
import CompareValue from '@/views/compare/CompareValue'
...
components: {
CompareValue
},
...
updateComponent: 0,
...
methods: {
reloadCompnent() {
this.updateComponent += 1;
},
getData() {
this.ocean.push({
userid: userId,
data1: this.result.data_john,
data2: this.result.data_mike,
data3: this.result.data_meika,
data4: this.result.data_slivina,
})
this.reloadCompnent() //Force the reload of the component
}
}
</script>
Child File:
<template>
{{ update }}
</template>
<script>
...
props: [
'ocean',
'update'
],
...
</script>
As far as I understood, a change of a normal variable triggers the component to be reloaded but it seems I oversee something.
Upvotes: 1
Views: 852
Reputation: 138216
Setting an existing Object
prop is actually reactive, and so is adding a new object to an array prop. In your example, getData()
would cause compare-value
to re-render without having to call reloadComponent()
(demo).
I read that VueJs can not detect a change in an Object.
You're probably referring to Vue 2's change-detection caveats for objects, which calls out addition or deletion of properties on the object.
Caveat example:
export default {
data: () => ({
myObj: {
foo: 1
}
}),
mounted() {
this.myObj.foo = 2 // reactive
delete this.myObj.foo // deletion NOT reactive
this.myObj.bar = 2 // addition NOT reactive
}
}
But Vue provides a workaround, using Vue.set()
(also vm.$set()
) to add a new property or Vue.delete()
(also vm.$delete()
) to delete a property:
export default {
//...
mounted() {
this.$delete(this.myObj, 'foo') // reactive
this.$set(this.myObj, 'bar', 2) // reactive
}
}
Upvotes: 2
Reputation: 437
thanks for the answers and I tested your suggested answer and I would have worked but I did something else. I just replaced the :update with :key and it worked. After this action the Component is automatically reloaded.
The solution looks exactly like the one i posted in the question just one (importatn) tiny little thing is different. See below.
<template>
<compare-value :ocean="ocean" :key="updateComponent" v-if="ocean.length > 0"></compare-value>
</template>
Thanks and hope it will help others too.
Br
Upvotes: 0