Search code examples
arraysvue.jscomponents

Vue: Array is only updated on console, not on screen


I'm still learning the basics of vue. I have different elements in one component, that have to be assigned in a second component. When I use console.log the array is shown correctly, but when i want to show the array in dynamically in template it is still the default value. What am I doing wrong?

Component one:

    <template>
    <div>
{{nr}}
{{containertyp}}
      <button  @click="click(0)"></button>
</div>
     </template>

I have many more buttons with different parameters, just to make it shorter here.

export default: {
data: function {
return {
nr: [],
containertyp: [],
    }
    }
methods: {
  click(number) {

    for (var i = 0; i < 27; i++) {
      this.nr[i] = false;
      if (number == i) {
        this.nr[i] = true;
      }
    };

    EventBus.$emit('containerclicked');

  }
},
created: function() {
  let i;
  //default
  for (i = 0; i < 27; i++) {
    this.nr[i] = false; 
  }
  for (var index = 0; index < 27; index++) {
    this.containertyp[index] = 'bs';
  }
},
mounted() {

  const self = this
  EventBus.$on('containertypchosen', function (containertyp) {
    for (let j = 0; j < 27; j++) {
      if (self.nr[j] == true) {
        self.containertyp[j] = containertyp
      }
    }
  })

Component two:

<template>
<div>
<button :disabled = "disabled == true"  v-on:click="chosetype('bs')" "> bs </button> <br />
</div>
</template>
export default: {
data: function() {
return {
disabled: true
}
}
     mounted () {
    const self = this
    EventBus.$on('containerclicked', function (){
      self.disabled = false

    })
  },
methods: {
chosetype: function (containertyp) {
      this.containertyp = containertyp
      EventBus.$emit('containertypchosen', containertyp)
    }

    }
}

Solution

  • You can't update arrays using indexes, the changes won't be detected by the reactivity system.

    https://v2.vuejs.org/v2/guide/list.html#Caveats

    So, for example, this won't work:

    this.nr[i] = true;
    

    Instead you'd need to use Vue.set, or the alias vm.$set:

    this.$set(this.nr, i, true);
    

    An alternative would be to create a new array and then replace this.nr entirely, i.e. this.nr = newArray.

    You'll need to make a similar change everywhere that you're updating an array by index. There are updates to both nr and containertyp that currently have this problem.

    It's not immediately clear from your code whether nr even needs to be an array. It seems that all the values are false apart from one, so you might be better off just holding the index of the true value instead of using an array.