最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - splice not working properly my object list VueJs - Stack Overflow

programmeradmin2浏览0评论

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 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

Share Improve this question edited Jan 28, 2018 at 9:13 Rishikesh Dhokare 3,58925 silver badges35 bronze badges asked Jan 28, 2018 at 9:08 locklock 7393 gold badges9 silver badges21 bronze badges 4
  • where does index come from in the click event? – dandavis Commented Jan 28, 2018 at 9:11
  • index from array list (rows), when fetch array get it (row,index) and send to remove function – lock Commented Jan 28, 2018 at 9:15
  • it actually works, you just can't tell because your html reflects only the iteration counter, not any data. if you inject something from the data, it looks fine: jsfiddle.net/duej8L3c ... – dandavis Commented Jan 28, 2018 at 9:37
  • Thanks a lot,that's work, Is there another way not inject value to input's ? (my inputs have dynamic name and id ) – lock Commented Jan 28, 2018 at 9:47
Add a comment  | 

1 Answer 1

Reset to default 16

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:

  • I corrected the fact counterrow was never incremented
  • I added a :key

The doc of :key : https://v2.vuejs.org/v2/guide/list.html#key

Here is another jsFiddle https://jsfiddle.net/BenoitNgo/2a1u1j2b/3/ with:

  • Adding a v-model
  • Displaying your data below your form
  • Corrected the fact counterrow was never incremented
  • Adding a :key
发布评论

评论列表(0)

  1. 暂无评论