2

I have an array of strings:

myList: ['First item', 'Second item']

I want to add a third, and more. I have a method that pushes an empty string onto the array:

this.myList.push('')

(Using .push on a Vue object is okay)

It now looks like this:

['First item', 'Second item', '']

Which I can now edit. However, it’s not bound to the array. When another item is added, the value is lost and it returns to an empty string.

var app = new Vue({
  el: '#app',
  data: function() {
    return {
      myList: ['First item', 'Second item']
    }
  },

  methods: {
    remove(index) {
      Vue.delete(this.myList, index)
    },
    add() {
      this.myList.push('')
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
  <p v-for="(listItem, index) in myList" class="my-2 field" :key="index">
    <input
      type="text"
      :value="listItem"
      :key="index"
    />
    <button @click.prevent="remove(index)">✕</button>
  </p>
  <p>
    <button @click.prevent="add()">Add</button>
  </p>
</div>

Tried the following:

As above:

<input
  type="text"
  :value="listItem"
  :key="index"
/>

Without key, same:

<input
  type="text"
  :value="listItem"
/>

With (incorrect) binding, doesn’t echo value:

<input
  type="text"
  :value="myList[index]"
/>

Using v-bind:

<input
  type="text"
  v-bind:value="listItem"
/>

And also with a key:

<input
  type="text"
  v-bind:value="listItem"
  v-bind:key="index"
/>

I’m positive that I’m going about this the wrong way. Hopefully you can see the behaviour that I’m trying to achive.


Update Have just tried using a v-model, but I get this error:

You are binding v-model directly to a v-for iteration alias. This will not be able to modify the v-for source array because writing to the alias is like modifying a function local variable. Consider using an array of objects and use v-model on an object property instead.

Is it perhaps easier to have an array of objects with one value?

2 Answers 2

5

you should use v-model to have a 2-way binding on your input and you have to use myList[index] cause v-bind directive requires an attribute value and not a v-for alias (as listItem). Try this:

var app = new Vue({
  el: '#app',
  data: function() {
    return {
      myList: ['First item', 'Second item']
    }
  },

  methods: {
    remove(index) {
      Vue.delete(this.myList, index)
    },
    add(listItem) {
      this.myList.push('')
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
  <p v-for="(listItem, index) in myList" class="my-2 field" :key="index">
    {{myList[index]}}
    <input
      type="text"
      v-model="myList[index]"
    />
    <button @click.prevent="remove(index)">✕</button>
  </p>
  <p>
    <button @click.prevent="add()">Add</button>
  </p>
</div>

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

Comments

2

The input is not bound with the array elements. Try this.

var app = new Vue({
  el: '#app',
  data: function() {
    return {
      myList: ['First item', 'Second item']
    }
  },

  methods: {
    remove(index) {
      Vue.delete(this.myList, index)
    },
    add() {
      this.myList.push('')
    }
  }
})
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
  <p v-for="(listItem, index) in myList" class="my-2 field" :key="index">
    <input
      type="text"
      v-model="myList[index]"
      :key="index"
    />
    <button @click.prevent="remove(index)">✕</button>
  </p>
  <p>
    <button @click.prevent="add()">Add</button>
  </p>
</div>

JSFiddle : https://jsfiddle.net/32d41epw/2/

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.