Reputation: 327
This is simplified version of bigger component I'm working on. Please help me to solve the mystery - why I'm getting error on deleting (splicing) the last item from the list ?
@click="handleProductLineTap(line, index)"
is removed at v-for - no error.
<template>
<div v-for="(row, index) in this.rows" :key="index" v-bind:id="`row-${index}`" @click="handleProductrowTap(index)">
<div v-bind:id="`row-${index}`" v-bind:class="rowCssDecorations(row, index)">
<span>{{ row.text }}</span> <button class="borderNormal" style="background-color: white; border:black;" @click.prevent="deleteRow(row, index)">Delete me </button>
</div>
</div>
</template>
<script>
export default {
name: 'TestRow',
created() {},
data() {
return {
rows: [
{'id':1, text: 'Granny smith', type: 'apple'},
{'id':2, text: 'Conference', type: 'pear'},
{'id':3, text: 'Alpine', type: 'strawberry'},
],
currentRowIndex: 0
}
},
methods: {
//returns css styling to every row in v-for.
//It sets color of the row according to the row.type and highlights selected row (if currentRowIndex == index).
rowCssDecorations(row) {
var resultingCss = ''
//change color according to rows.type
switch (row.type) {
case 'apple':
resultingCss = resultingCss + 'appleClass'
break
case 'pear':
resultingCss = resultingCss + 'pearClass'
break
case 'strawberry':
resultingCss = resultingCss + 'strawberryClass'
break
default:
resultingCss = resultingCss + 'defaultClass'
break
}
//Hliglight the current row
if (this.rows[this.currentRowIndex].id == row.id) {
resultingCss = resultingCss + ' borderSelected '
} else {
resultingCss = resultingCss + ' borderNormal '
}
return resultingCss
},
//deletes the row
deleteRow(index) {
this.rows.splice(index, 1)
},
//Simply sets the selected row id to currentRowIndex .
handleProductrowTap( index) {
this.currentRowIndex = index
},
},
}
</script>
<style lang="scss" scoped>
.appleClass {
background-color: greenyellow;
}
.pearClass {
background-color: palegoldenrod;
}
.strawberryClass {
background-color: red;
}
.defaultClass {
background-color: gainsboro;
}
.borderSelected{
border-color: black;
border-width: 4px;
}
.borderNormal{
border-color: black;
border-width: 2px;
}
</style>
Upvotes: 0
Views: 213
Reputation: 27192
After looking into the fiddle link you shared, I came up with below observations/root cause :
You are calling deleteRow
method with two parameters (row, index) but in the method definition you are accepting only index
which causing the issue in delete the record.
To resolve this you have to just pass the index in deleteRow
method from the template.
Another observation is that as you are passing row
and index
both in rowCssDecorations
method. Hence, no need of currentRowIndex
, you can directly use the index
in rowCssDecorations
method.
Live Demo :
new Vue({
el: '#app',
data: {
rows: [{
'id': 1,
text: 'Granny smith',
type: 'apple'
},
{
'id': 2,
text: 'Conference',
type: 'pear'
},
{
'id': 3,
text: 'Alpine',
type: 'strawberry'
}
],
currentRowIndex: 0
},
methods: {
deleteRow(index) {
this.rows.splice(index, 1)
},
rowCssDecorations(row, index) {
var resultingCss = ''
//change color according to rows.type
switch (row.type) {
case 'apple':
resultingCss = resultingCss + 'appleClass'
break
case 'pear':
resultingCss = resultingCss + 'pearClass'
break
case 'strawberry':
resultingCss = resultingCss + 'strawberryClass'
break
default:
resultingCss = resultingCss + 'defaultClass'
break
}
//Hliglight the current row
if (this.rows[index].id == row.id) {
resultingCss = resultingCss + ' borderSelected '
} else {
resultingCss = resultingCss + ' borderNormal '
}
return resultingCss
},
//deletes the row
deleteRow(index) {
this.rows.splice(index, 1)
}
}
})
.appleClass {
background-color: greenyellow;
}
.pearClass {
background-color: palegoldenrod;
}
.strawberryClass {
background-color: red;
}
.defaultClass {
background-color: gainsboro;
}
.borderSelected {
border-color: black;
border-width: 4px;
}
.borderNormal {
border-color: black;
border-width: 2px;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<div v-for="(row, index) in this.rows" :key="index" v-bind:id="`row-${index}`">
<div v-bind:id="`row-${index}`" v-bind:class="rowCssDecorations(row, index)">
<span>{{ row.text }}</span> <button class="borderNormal" @click.prevent="deleteRow(index)">Delete me</button>
</div>
</div>
</div>
Upvotes: 1