Chris
Chris

Reputation: 437

VueJs force component to reload

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

Answers (2)

tony19
tony19

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

Chris
Chris

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

Related Questions