0

In my example, i have two arrays. First array - values, second - zeros for incremental counter. Any new item have own counter button for him. But it is not working, and i do not know why. If i push several buttons, i see chaotioc behavior in arrays

JSfiddle

  1. How to repair it?
  2. How to do counter function without button?

    Example: if i loading page, i see 3 elements. Counters begining counting from 0. After 10 seconds i add new element. Old counters continue to work, but counter in new element start from 0.

new Vue({
	el: '#page',
  data: {
  	arr: [1, 2 ,3],
    count: [0, 0 ,0]
  },
  methods: {
  	addEll: function() {
    	this.arr.push(this.arr.length + 1);
      this.count.push(0);
    },
    incrementio: function(val) {
        interval = setInterval(() => {
        Vue.set(this.count, this.count[val], 0);
        this.count[val]++;
      }, 1000);
     },
  },
  computed: {
  	visibleList: function(){
    	return this.arr;
    }
  }
  
})
<script src="https://unpkg.com/vue"></script>

<div id="page">
<button v-on:click="addEll">Add element</button>
{{ arr }}
{{ count }}
  <ul>
    <li v-for="(item, index) in visibleList">
        {{item}}
        <button v-on:click="incrementio(index)">Counter: {{count[index]}}</button>
    </li>
  </ul>
</div>

3 Answers 3

1

I don't clearly understand from question what your counter should do, but i think it needs to change these lines

Vue.set(this.count, this.count[val], 0);
this.count[val]++;

to this 1 line:

Vue.set(this.count, val, this.count[val]+1);

And I think you need to change setInterval to setTimeout.

Here is updated jsfiddle.

Sign up to request clarification or add additional context in comments.

Comments

0

If I understand correctly you trying to count lifetime of each value. Here is my approach. Firstly I tied the value and its counter together in one object as I find it more efficient. Moving on, I defined interval property, because not doing so (The compiler automatically defines it in global scope) may cause unwanted behaviour and it is regarded as an error in strict mode. I also removed unnecessary visibleList computed property from your code. And last but not least I added clearInterval function in beforeDestroy hook as it is a good habit. (In your particular case it might be unnecessary to do so but if it was a component reused many times it would be very important to have it as it frees up the memory.)

new Vue({
  el: '#page',
  data: {
    arr: [{
      value: 1,
      counter: 0
    }],
    interval: null
  },
  mounted () {
    this.interval = setInterval(() => {
      this.arr.map(x => x.counter++);
    }, 1000);
  },
  beforeDestroy () {
    clearInterval(this.interval);
  },
  methods: {
    addEll () {
      this.arr.push({
        value: this.arr.length + 1,
        counter: 0
      });
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>

<div id="page">
  <button v-on:click="addEll">Add</button> {{ arr }}
  <ul>
    <li v-for="(item, index) in arr">
      {{item.value}} Counter: {{item.counter}}
    </li>
  </ul>
</div>

Comments

0

As you can see in the Vuejs documentation Vuejs Caveats

Vue cannot detect the following changes to an array:

  • When you directly set an item with the index, e.g. vm.items[indexOfItem] = newValue
  • When you modify the length of the array, e.g. vm.items.length = newLength

To overcome caveat 1, both of the following will accomplish the same as vm.items[indexOfItem] = newValue, but will also trigger state updates in the reactivity system:

Vue.set(vm.items, indexOfItem, newValue)

The example would be like this:

new Vue({
  el: '#page',
  data: {
    arr: [1, 2 ,3],
    count: [0, 0 ,0]
  },
  methods: {
    addEll: function() {
       this.arr.push(this.arr.length + 1);
       this.count.push(0);
    },
    incrementio: function(index) {
       this.$set(this.count, index, this.count[index] + 1)
    },
  },
  computed: {
     visibleList: function(){
       return this.arr;
     }
  }
})

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.