Aquaguy
Aquaguy

Reputation: 367

Unexpected behaviour removing a child component (row)

Description:

I have a table with some products, each row is a custom vue <row> component.

Each element has a closing (removing) button that triggers the custom "remove" event. The main app listens to this event and removes the children (by index)

The row a part from some static text it contains an input with a number.

The problem:

The parent (Vue app) removes the row, but the value of the input is then moved (and replaces its previous value) to the input in the next row.

Expected behaviour:

I want to simply remove the item I do not care about the value of the text input once it's removed. It should not move its value to the next sibling.

I attach an example.

let row = Vue.component('row', {
  name: 'row',
  props: ['number', 'name', 'sq'],
  data: () => ({
    quantity: 0
  }),
  template: '<tr>' +
    '<td>{{number}}</td>' +
    '<td>{{name}}</td>' +
    '<td><button v-on:click="quantity--">-</button><input type="text" :value="quantity"><button v-on:click="quantity++">+</button></td>' +
    '<td><button v-on:click="remove">&times;</button></td>' +
    '</tr>',
  methods: {
    remove: function() {
      this.$emit('remove', this.quantity)
    }
  },
  beforeMount() {
    this.quantity = this.sq
  }

})


new Vue({
  el: "#app",
  data: {
    out: [],
    rows: [{
        name: "Icecream",
        sq: 0
      },
      {
        name: "Sugar cube",
        sq: 50
      },
      {
        name: "Peanut butter",
        sq: 0
      },
      {
        name: "Heavy cream",
        sq: 0
      },
      {
        name: "Cramberry juice",
        sq: 0
      }
    ]
  },
  methods: {
    removeRow: function(index, quantity) {
      this.out.push(`Removing row ${index} (${this.rows[index].name} | ${quantity} units)`)
      this.rows.splice(index, 1)
    }
  },
  computed: {
    log: function() {
      return this.out.join("\r\n")
    }
  }
})
body {
  background: #20262E;
  padding: 20px;
  font-family: Helvetica;
}

h2 {
  font-weight: bold;
  margin-bottom: 10px;
}

#app {
  background: #fff;
  border-radius: 4px;
  padding: 20px;
  transition: all 0.2s;
}

td {
  padding: 4px 5px;
}

input {
  width: 40px;
  text-align: center;
}

h4 {
  margin-top: 20px;
  margin-bottom: 5px;
}

#log {
  padding: 10px;
  background: #20262E;
  color: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.16/vue.min.js"></script>
<div id="app">
  <h2>Cart:</h2>
  <table>
    <row v-for="(row, index) in rows" :number="index" :name="row.name" :sq="row.sq" v-on:remove="removeRow(index, $event)"></row>
  </table>

  <h4>Log</h4>
  <pre id="log" v-html="log"></pre>
</div>

Upvotes: 2

Views: 87

Answers (1)

Aquaguy
Aquaguy

Reputation: 367

As @Bert mentioned in the comments. The problem was that I was missing a key.

https://v2.vuejs.org/v2/api/#key

Adding it solved the problem Thanks

Upvotes: 1

Related Questions