0

I'am trying to implements dynamic adding and removing components in Vue.js.

There is a problem with slice method, basically it should remove element from array by passed index. To mutate an array i use slice(i,1) .

According to this answer, modifying array in this way should help me, but is's not working.

What i am doing wrong?

Here is my code and a codepen:

<div id="app">
  <button @click="addNewComp">add new component</button>
  <template  v-for="(comp,index) in arr">
    <component 
     :is="comp"
     :index="index"
     @remove-comp="removeComp(index)"
     ></component>
  </template>
</div>
<script type="text/x-template " id="compTemplate"> 
  <h1> I am a component {{index}} 
  <button v-on:click="$emit('remove-comp')">X</button>
  </h1>
</script>

 const newComp = Vue.component("newComp",{
  template:"#compTemplate",
  props:['index']
})

new Vue({
  el:"#app",
  data:{
    arr:[newComp]
  },
  methods:{
    addNewComp:function(){
      this.arr.push(newComp);
        console.log(this.arr);
    },
    removeComp:function(i){
      console.log(i);
       this.arr.slice(i,1);
       console.log(this.arr);
    }
  }
})

2 Answers 2

3

 const newComp = Vue.component("newComp",{
  template:"#compTemplate",
  props:['index']
})

new Vue({
  el:"#app",
  data:{
    arr:[newComp]
  },
  methods:{
    addNewComp:function(){
      this.arr.push(newComp);
    },
    removeComp:function(i, a){
      console.log('i', i, a, typeof i);
      this.arr.splice(i,1);
    }
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17-beta.0/vue.js"></script>
<div id="app">
  <button @click="addNewComp">add new component</button>
  <template  v-for="(comp,index) in arr">
    <component 
     :is="comp"
     :index="index"
     @remove-comp="removeComp(index, 100+index)"
      :key="`${index}`"
     ></component>
  </template>
</div>
<script type="text/x-template " id="compTemplate"> 
  <h1> I am a component {{index}} 
  <button v-on:click="$emit('remove-comp')">X</button>
  </h1>
</script>

I read this before its to do with Vue and reactive states. .slice() is non-reactive so it returns a copy of the data without altering the original( i.e. non-reactive). Use the .splice() which is reactive or even better look at the .filter() here

Sign up to request clarification or add additional context in comments.

5 Comments

It's working, but now it remove only last item from array. Why this could happen?
Ok, now I get it. Thanks
@NazarKotsyuba no thats not right i removed the comment. All that does is replaces the element with the third parameter dont do that. So i have had a mess around with the code it doesnt just remove the end. the .splice(i,1) works but its just everything is reactive so say if you have a array size 0-9 and remove the index 2, the 10th element becomes the 9th. Its reactive so when you remove the element from the array all integers above it get -1. If you understand
Look at the snippet above and look at the a parameter in the log
Aha, so to summarize: it's remove correct component, but because of reactivity all next components change their numbers.
0

You're using the slice method instead of the splice one as mentioned in the link you provided.

deleteEvent: function(index) {
  this.events.splice(index, 1);
}

1 Comment

Yes, i just noticed it too.. Thank you)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.