[Vuejs]-Vue removing wrong HTML node in dynamic list of components

4👍

I’ve managed to fix the issue thanks to this documentation.

The crux of it is if you don’t have a unique key already, you need to store the array index of the object in the object itself, this is because as you mutate the source array you are also mutating it’s keys and as far a Vue is concerned when it renders, the last item is missing, not the removed item.

views: [
  {index: 0, type: 'content-longtext', model: 'test1'},
  {index: 1, type: 'content-longtext', model: 'test2'},
  {index: 2, type: 'content-longtext', model: 'test3'},
  {index: 3, type: 'content-longtext', model: 'test4'},
  {index: 4, type: 'content-longtext', model: 'test5'},
],

...

newContentBlock(type) {
  this.views.push({index: this.views.length, type: 'content-longtext', model: ''})
},

Once you have stored the array index you need to add the :key binding to the iterator in the template, and bind that stored value.

<div v-for="(currentView, index) in views" :key="currentView.index">
  <component :is="currentView.type" :model="currentView.model" :update="updateContent(index)"></component>
  <a v-on:click="removeContent(index)">Remove</a>
</div>

Finally you must make sure you preserve the integrity of your indexes when you mutate the array.

removeContentBlock(index) {
  this.views
    .splice(index, 1)
    .map((view, index) => view.index = index)
},

https://jsfiddle.net/afz6jjn0/5/

Leave a comment