4

I need to be able to delete specific component from the array. I do this with splice and although that component definition is removed from array, vuejs removes wrong component. It allways removes the last added component.

Here is a fiddle that provides demonstration of that:

https://jsfiddle.net/wjjonm8n/

and here is video to show what is happening:

https://maxniko.tinytake.com/sf/MTg3NTI5NF82MDIxNDAx

here is some code:

Vue.component('row-component', {
    props: ["rowData", "uniqueId"],
    mounted: function() {
        console.log('mounting: ' + this.uniqueId)
    },
    beforeDestroy: function() {
      console.log('removing: ' + this.uniqueId)
    },
    template: `
        <div>
            row component: {{rowData}}
            <button @click="$emit('delete-row')">Delete</button>
        </div>`
})

new Vue({
    el: '#app',
    template: `
        <div>
            <row-component v-for="(row, index) in rows" :row-data="row" :uniqueId="index" v-on:delete-row="deleteThisRow(index)"></row-component>
            <button @click="add()">add</button>
        </div> 
    `,
    data: {
        rows: ["line1", "line2", "line3", "line4", "line5"],

    },
    methods: {
            add() {
            this.rows.push('line'+(this.rows.length+1))
        },
        deleteThisRow: function(index) {
            this.rows.splice(index, 1)

            console.log(this.rows)
        }
    }
})

this function tells me what vuejs really removes:

    beforeDestroy: function() {
      console.log('removing: ' + this.uniqueId)
    }

it removes last added component if you look at what that console.log function prints. This is problem because on mount of each component I create listener for just that component:

this.$bus.$on('column-'+this.uniqueId+'-add-block', this.handlerMethod)

when vue removes last component, this event listener no longer works.

How can I solve this?

In my own application this is how I create child component:

let column = new Object()
column.uniqueId = this._uid+'-column-' + this.addedColumnCount
column.text = '1/2'
this.columnList.push(column)
this.addedColumnCount = this.addedColumnCount + 1

notice how I create uniqueId for component when I add it:

column.uniqueId = this._uid+'-column-' + this.addedColumnCount

when I try to delete a component it allways reports to me that the component with last added uniqueId is being removed.

    beforeDestroy: function() {
        this.$bus.$off('column-'+this.uniqueId+'-add-block', this.handlerMethod)
        console.log('removing: ' + this.uniqueId)
    },

1 Answer 1

11

You do not have a :key binding to tell Vue which row goes with which component. Vue uses shortcuts to make the view look the same as the state of the viewmodel. If you add :key="row" to the v-for, it works.

Updated fiddle

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

1 Comment

Hi, I've run into a problem now when I delete a row and that row has other rows created after it then all those rows are destryoed and recreated, here is a video of it: maxniko.tinytake.com/sf/MTg3NTc2M182MDIyMzI5 you can test it here: jsfiddle.net/xk5yL3h8 not sure why this is happening, I have moved delete button from the child component up the the parent and moved v-for into a div that holds the row-component. How can I avoid by deleting first row-component that all other row-components after it are destyroed as well and then recreated?

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.