Reputation: 13667
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?
Upvotes: 2
Views: 9110
Reputation: 91
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>
Upvotes: 5
Reputation: 9259
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/
Upvotes: 2