Difficulty to remove item from inverted list in Vue

Asked

Viewed 398 times

1

I’m picking up at the time of using list in Vue. I display on the screen a list reversed by a computed. I need to display it upside down so when I add an item it shows up on top. Only the way I did Vue is lost when removing the correct item from the list.

See my code: https://jsbin.com/jutuyenubi/edit?html,js,console,output

I made a button to add, which works properly. Already in "remove" I use the index of the item in the list to make a splice(), only Vue uses this index in the inverted list, I imagined that it would use in the original list and then invert.

2 answers

2

Hello

The changes I would make to the code would be adding key property to html and using the item itself as a reference for removal:

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta name="viewport" content="width=device-width">
  <title>JS Bin</title>
</head>
<body>
  <div id="box">
    <button @click="add">button</button>
    <ul>
      <li v-for="(item, index) in reverse" :key="item.id">
        {{ item.name }} - <span class="del" @click="del(item)">remover</span>
      </li>
    </ul>
  </div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.0.3/vue.js"></script>

</body>
</html>

And in the JS:

new Vue({
  el: '#box',
  data: {
    list: [
      {id: 1, name: 'item 1'},
      {id: 2, name: 'item 2'},
      {id: 3, name: 'item 3'}
    ]
  },
  methods: {
    add: function(){
      this.list.push({id: 100, name: 'novo item'})
    },
    del: function(item){
      alert(item.id)
      this.list.splice(this.list.indexOf(item), 1)
    }
  },
  computed: {
    reverse: function(){
      return this.list.slice().reverse()
    }
  }
})
  • Thanks man, solved my problem.

  • Face your answer works, but is as Sergio commented, gives problem with immutable objects. I started having problems that were solved using Sergio’s solution.

1


You have to use the index reversed also in the argument of that function like this:

reverse.length - 1 - index

Another way would be to pass the id and then do

this.list = this.list.filter(obj => obj.id !== id)

or pass the item itself:

this.list = this.list.filter(obj => obj !== item)

Example with index reversed:

new Vue({
  el: '#box',
  data: {
    list: [{
        id: 1,
        name: 'item 1'
      },
      {
        id: 2,
        name: 'item 2'
      },
      {
        id: 3,
        name: 'item 3'
      }
    ]
  },
  methods: {
    add: function() {
      this.list.push({
        id: 100,
        name: 'novo item'
      })
    },
    del: function(index) {
      alert(index)
      this.list.splice(index, 1)
    }
  },
  computed: {
    reverse: function() {
      return this.list.slice().reverse()
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
<div id="box">
  <button @click="add">button</button>
  <ul>
    <li v-for="(item, index) in reverse">
      {{ item.name }} - <span class="del" @click="del(reverse.length - 1 - index)">remover</span>
    </li>
  </ul>
</div>

  • Your reply was excellent, nice idea to use the filter but the answer from @Jozimar Back was simpler.

  • 1

    @Feliperabbit great, it’s a matter of preference, I don’t like the .splice because it does not apply the logic of immutable that I prefer. But the other answer is good and gave +1 also :)

  • You’re right about the subject of immutable objects, my application was 100% correct using your option.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.