I have a Object array but when i want remove a object from array list only items are deleted from the end
Html :
<div id="app">
<table>
<tr>
<td><input type="text" name="test1" /></td>
<td>
<button class="btn" @click="addrow">add row</button>
</td>
</tr>
<tr v-for="(row,index) in rows">
<td><input type="text" name="test2" /></td>
<td>
<button class="btn" @click="removerows(index)">remove </button>
</td>
</tr>
</table>
</div>
Js:
new Vue({
el: "#app",
data: {
counterrow:1,
rows:[],
},
methods: {
addrow:function(){
this.rows.push({
id:this.counterrow
});
},
removerows:function(index){
this.rows.splice(index,1);
},
},
});
Splice(index,1) not working correctly and just remove the last elements per delete , live demo : jsfiddle
I think you probably missunderstand what is going on:
In VueJS there is a caching method which allow the reusing of existing component generated: - Each of your object are considered equals when rendered (at a DOM level).
So VueJS remove the last line because it is probably ask the least calculation and then recalcul the expected state. There are many side case to this (sometime, the local state is not recalculated). To avoir this: As recommended in the documentation, use :key
to trace the id of your object. From the documentation:
When Vue is updating a list of elements rendered with v-for, by default it uses an “in-place patch” strategy. If the order of the data items has changed, instead of moving the DOM elements to match the order of the items, Vue will patch each element in-place and make sure it reflects what should be rendered at that particular index. This is similar to the behavior of track-by="$index" in Vue 1.x.
This default mode is efficient, but only suitable when your list render output does not rely on child component state or temporary DOM state (e.g. form input values).
To give Vue a hint so that it can track each node’s identity, and thus reuse and reorder existing elements, you need to provide a unique key attribute for each item. An ideal value for key would be the unique id of each item. This special attribute is a rough equivalent to track-by in 1.x, but it works like an attribute, so you need to use v-bind to bind it to dynamic values...
temporary DOM state : Here it refer to your behaviour.
There is your corrected code (associated fiddle: https://jsfiddle.net/BenoitNgo/3Lrmswc5/):
HTML:
<div id="app">
<table>
<tr>
<td><input type="text" name="test1" /></td>
<td><button class="btn" @click="addrow">add row</button></td>
</tr>
<tr v-for="(row,index) in rows" :key="row.id">
<td><input type="text" name="test2"/></td>
<td><button class="btn" @click="removerows(index)" >remove </button></td>
</tr>
</table>
</div>
In your javascript:
new Vue({
el: "#app",
data: {
counterrow:1,
rows:[],
},
methods: {
addrow:function(){
this.counterrow += 1;
this.rows.push({
id:this.counterrow,
model: ""
});
},
removerows:function(index){
this.rows.splice(index,1);
},
},
});
In this code:
counterrow
was never incremented:key
The doc of :key
: https://vuejs.org/v2/guide/list.html#key
Here is another jsFiddle https://jsfiddle.net/BenoitNgo/2a1u1j2b/3/ with:
counterrow
was never incremented:key
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With