bgul
bgul

Reputation: 146

V-model array item cannot updating in spite of having reference

My main purpose is collecting the requested quantity for multiple inventories(future usage).

* I tried to make a counter for referenced v-models. I made out something like this. But it doesn't work:

new Vue({
    el: '#app',
    data: {
      counter: []
    },
    methods: {
      increment(x) { 
        this.counter[x]++
      }
    }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div v-for="i in 2">
  <div><input type="text" v-model="counter[i]"></div>
  <button v-on:click="increment(i)">Increment</button>
  </div>
</div>

Is there a different way to do this? Am I missing something?

Upvotes: 1

Views: 40

Answers (2)

connexo
connexo

Reputation: 56773

This may not be beautiful, but it works:

var vm = {
  el: '#app',
  data: {
    counterel1: 0,
    counterel2: 0,
  },
  methods: {
    increment(x) {
      this.counter[x-1]++;
      console.log(this.counter);
    }
  }
}

vm.data.counter = [vm.data.counterel1, vm.data.counterel2];

new Vue(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <div v-for="i in 2">
    <div><input type="text" v-model="counter[i]"></div>
    <button v-on:click="increment(i)">Increment</button>
  </div>
</div>

Upvotes: 0

Ayrton
Ayrton

Reputation: 2303

Your code doesn't work for two reasons:

A) Your array is empty, so when you use counter[i] as v-model you're using undefined, which can't be incremented.

B) You're mutating your array by index, which doesn't work well with Vue. To mutate arrays, you should use methods like push or splice.

To fix your code, you must address your two issues. That is, you must initialize your array with numeric values and mutate your array via functions, like this:

new Vue({
el: '#app',
data: {
    counter: [0, 0]
},
methods: {
    increment(x) { 
        this.counter.splice(x, 1, this.counter[x] + 1);
    }
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
    <div v-for="(val, i) in counter">
        <div><input type="text" v-model="counter[i]"></div>
        <button v-on:click="increment(i)">Increment</button>
    </div>
</div>

Note that I also changed your template to use (val, i) in counter instead of i in 2. That is done so that you can access your array from the starting index. val is the element, i is the index, so you use i to increment your array.

Also note the use of splice. What it does is replacing the xth element of your array with it's own xth element, but incremented.

Upvotes: 2

Related Questions