Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

use v-model inside a v-for loop

I am rendering an input field inside v-for loop and using v-model in that input to get the value of the input but when i type in any one of the input , the value is typed in every text field.

I have replicated my issue here in this fiddle

<div id="app">
  <h2>Todos:</h2>
  <ol>
    <li v-for="todo in todos">
      <label>
        <input type="text" v-model="score">

        <del v-if="todo.done">
          {{ todo.text }}
        </del>
        <span v-else>
          {{ todo.text }}
        </span>
      </label>
    </li>
  </ol>
</div>

new Vue({
  el: "#app",
  data: {
    score: [],
    todos: [
      { text: "Learn JavaScript", done: false },
      { text: "Learn Vue", done: false },
      { text: "Play around in JSFiddle", done: true },
      { text: "Build something awesome", done: true }
    ]
  },
})
like image 713
Raaz Avatar asked Sep 27 '18 06:09

Raaz


People also ask

Can you have multiple V models?

v-model gives us the flexibility to add multiple v-model directives on a single component instance and the modelValue can also be renamed according to our preference.

What is the difference between v-model and V-bind?

v-bind is a one-way binding. v-model is used for binding form elements like inputs, radio buttons, textarea, checkboxes. It is used for binding data, attributes, expressions, class, styles. V-model is input value sensitive.

Is v-model two way binding?

The v-model directive makes two-way binding between a form input and app state very easy to implement. One can bind a form input element and make it change the Vue data property when the content of the field changes.

Can v-model be an array?

To use v-model on an array with multiple inputs with Vue. js, we can use the v-for directive to render the array. Then we use v-model to bind to the properties of each object. to use v-for to render the finds array into divs.


2 Answers

Yes obviously that happens because you bind X Input fields on 1 Value. What you probably want is your score[] to get put in as an Array, for that use

new Vue({
  el: "#app",
  data: {
    score: [],
    todos: [
      { text: "Learn JavaScript", done: false },
      { text: "Learn Vue", done: false },
      { text: "Play around in JSFiddle", done: true },
      { text: "Build something awesome", done: true }
    ]
  },
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

li {
  margin: 8px 0;
}

h2 {
  font-weight: bold;
  margin-bottom: 15px;
}

del {
  color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <h2>Todos:</h2>
  <ol>
    <li v-for="(todo,index) in todos">
      <label>
    <input type="text" v-model="score[index]">

    <del v-if="todo.done">
      {{ todo.text }}
    </del>
    <span v-else>
      {{ todo.text }}
    </span>
  </label>
    </li>
  </ol>
</div>

https://jsfiddle.net/o9awn47v/

like image 164
Badgy Avatar answered Sep 24 '22 07:09

Badgy


Score is treated as a single variable, when in it used in v-model="score".

You can add the score in the todo items and v-model it on the input, so you can easily reference to the score value of each todo item.

<div id="app">
  <h2>Todos:</h2>
  <ol>
    <li v-for="todo in todos">
      <label>
        <input type="text" v-model="todo.score">

        <del v-if="todo.done">
          {{ todo.text }}
        </del>
        <span v-else>
          {{ todo.text }}
        </span>
      </label>
    </li>
  </ol>
</div>

new Vue({
  el: "#app",
  data: {
    todos: [
      { text: "Learn JavaScript", done: false, score: '' },
      { text: "Learn Vue", done: false, score: '' },
      { text: "Play around in JSFiddle", done: true, score: '' },
      { text: "Build something awesome", done: true, score: '' }
    ]
  },
})
like image 35
Ariel Conde Avatar answered Sep 21 '22 07:09

Ariel Conde