Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

deleting component from array, vuejs removes wrong component

Tags:

vue.js

vuejs2

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)
    },
like image 587
niko craft Avatar asked Dec 19 '22 04:12

niko craft


1 Answers

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

like image 141
Roy J Avatar answered Mar 02 '23 01:03

Roy J