monkeyman
monkeyman

Reputation: 135

Vue delete child component

I have this code:

Vue.component('parent', {
  template: `
    <div>
      <child v-for='(child, index) in children' :key='index' :childNumber="index+1" v-on:removeChild="removeChild" />
    </div>
  `,
  data: function() {
    return {
      children: [{}, {}, {}]
    }
  },
  methods: {
    removeChild: function(index) {
      this.children.splice(index, 1);
    }
  }
});

Vue.component('child', {
  template: `
    <div>
      <input :value="'I am child number: '+childNumber"></input>
      <button v-on:click="removeChild">Remove child {{childNumber}}</button>
    </div>
  `,
  data: function() {
    return {}
  },
  methods: {
    removeChild: function() {
      this.$emit('removeChild', this.childNumber);
    }
  },
  props: ['childNumber']
});

const app = new Vue({
    el: '#app',
    data: {
        message: 'Hello Vue!',
    }
});

At the moment when you click any of the "remove" buttons, it deletes the last child, regardless of which button you clicked. How can I change my code so that it deletes the child you think it will delete, without touching the other children? (ie. clicking "Remove child 2" will leave just child 1 and 3 on the screen)

Fiddle: https://jsfiddle.net/wgr3sxqr/6/

Upvotes: 0

Views: 3140

Answers (1)

Abdelaziz Mokhnache
Abdelaziz Mokhnache

Reputation: 4349

you can not view the changes when using empty children.

The problem you are facing is:

After you delete any child (supposing the child 1), the component will re-render. And since your naming is based on the indexes only, you will always see the children (1 and 2) left. the reason is because child 2 became 1 and the child 3 became 2 and so on.

Solution

try adding a name property to each component to view the difference. also because childNumber is index + 1 you have to subtract 1 from the index in the delete method.

here is a working Fiddle of your case.

here is the updated code:

Vue.component('parent', {
  template: `
    <div>
      <child v-for='(child, index) in children' :key='index' :childNumber="index+1" 
             v-on:removeChild="removeChild" :name="child.name"/>
    </div>
  `,
  data: function() {
    return {
      children: [{name: 'child 1'}, {name: 'child 2'}, {name: 'child 3'}]
    }
  },
  methods: {
    removeChild: function(index) {
      this.children.splice(index - 1, 1);
    }
  }
});

Vue.component('child', {
  template: `
    <div>
      <input :value="'I am ' + name"></p>
      <button v-on:click="removeChild">Remove {{name}}</button>
    </div>
  `,
  data: function() {
    return {}
  },
  methods: {
    removeChild: function() {
      this.$emit('removeChild', this.childNumber);
    }
  },
  props: ['childNumber', 'name']
});
const app = new Vue({
    el: '#app',
    data: {
        message: 'Hello Vue!',
    }
});

Upvotes: 2

Related Questions