Home > Blockchain >  Changes made to a computed array won't show after a prop binding
Changes made to a computed array won't show after a prop binding

Time:02-20

I'm quite new to vue and right now I'm trying to figure out how to make changes to a computed array and make an element react to this change. When I click the div element (code section 4), I want the div's background color to change. Below is my failed code.

Code section 1: This is my computed array.

computed: {
        arrayMake() {
            let used = [];
            for (let i = 0; i < 5; i  ) {
                used.push({index: i, check: true});
            }
            return used;

Code section 2: This is where I send it as a prop to another component.

<test-block v-for="(obj, index) in arrayMake" v-bind:obj="obj" v-on:act="act(obj)"></card-block>

Code section 3: This is a method in the same component as code section 1 and 2.

methods: {
        act(obj){
            obj.check = true;
        }

Code section 4: Another component that uses the three sections above.

props: ["obj"],
    template: /*html*/`
 <div v-on:click="$emit('act')">
        <div v-bind:style="{ backgroundColor: obj.check? 'red': 'blue' }">
        </div>
    </div>

CodePudding user response:

Easiest way to achieve this, store the object into another data prop in the child component.

child component

data() => {
  newObjectContainer: null
},
onMounted(){
  this.newObjectContainer = this.obj
},
methods: {
  act(){
    // you don't need to take any param. because you are not using it.
    newObjectContainer.check = !newObjectContainer.check
  }
}
watch: {
  obj(val){
     // updated if there is any changes
     newObjectContainer = val
  }
}

And if you really want to update the parent component's computed data. then don't use the computed, use the reactive data prop.

child component:

this time you don't need watcher in the child. you directly emit the object from the method

methods: {
  act(){
    newObjectContainer.check = !newObjectContainer.check
    this.emits("update:modelValue", nextObjectContainer)
  }
}

parent component:

data() => {
  yourDynamicData: [],
},
onMounted(){
   this.yourDynamicData = setAnArray()
},
methods(){
   setAnArray(){
      let used = [];
      for (let i = 0; i < 5; i  ) {
          used.push({index: i, check: true});
      }
      return used;
   }
}

okay above you created a reactive data property. Now you need the update it if there is a change in the child component,

in the parent first you need object prop so, you can update that.

<test-block v-for="(obj, index) in arrayMake" v-model="updatedObject" :obj="obj"></card-block>

data() => {
  yourDynamicData: [],
  updatedObject: {}
},
watch:{
  updatedObject(val){
     const idx = val.index
     yourDynamicData[idx] = val
  }
}
  • Related