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 }
    ]
  },
})

Solution 1:

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/

Solution 2:

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: '' }
    ]
  },
})

Solution 3:

Encountered a similar issue where I needed to input formdData for each table fields(form-input) but using a v-for to render all the table questions resulted in all the fields being field whenever I enter something in any of the fields. Checked your the above solutions tried it out but it didn't work for me.

<div class="option-section" v-if="question.type === 'TABLE'">
<table class="table b-table table-bordered">
 <thead>
   <tr>
   <th v-for="(column, index) in question.columns" :key="index">
    {{column.body}}
    </th>
    </tr>
  </thead>
 <tbody>
  <tr>
 <td v-for="(column, colindex) in question.columns" :key="colindex">
 <b-form-input size="sm" id="colindex" autocomplete="off"
 class="readonly" readonly disabled></b-form-input>
 </td>
 </tr>
 </tbody>
 </table> 
</div>

finally I discovered how to go about it and want to share should in case anyone face a similar situation.

<div class="option-section" v-if="question.type === 'TABLE'">
  <table class="table b-table table-bordered">
    <thead>
     <tr>
     <th v-for="(column, index) in question.columns" :key="index">
     {{column.body}}
     </th>
   </tr>
 </thead>
  <tbody>
   <tr>
   <td v-for="(column, colindex) in question.columns" :key="colindex">
    <b-form-input v-model="question.columns[colindex].response" id="colindex" :disabled="readOnly" size="sm" autocomplete="off" class="readonly" >
 </b-form-input>
 </td>
 </tr>
  </tbody>
   </table>
</div>