Search code examples
javascriptvue.jsvuejs2vue-componentreload

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.


Solution

  • 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
      }
    }