I am currently using v-for to print out the list of 'parties' elements where each 'party' is represented by a <base-card>. When I use the splice() on the additionalInfoList array which represents the array of 'parties' and I log the output on the console, I see that the correct element has been deleted from the array. However, when I observe the output on the screen, Vue somehow manages to delete either the last element of the array or the adjacent element from the list. Based on various suggestions and research, I have used the unique :key to help Vue, but it still gives me this pernicious bug.
BaseCardList.vue
<template>
<div>
<ul>
<base-card v-once
@add-parties="updateAdditionalInfoList"
@delete-party="deleteParty">
<template v-slot:title>
<slot></slot>
</template>
</base-card>
<base-card
v-for="(data) in additionalInfoListComputed" :key="JSON.stringify(data.id)"
ref="childComponent"
@add-parties="updateAdditionalInfoList"
@delete-party="deleteParty">
<!-- Wrapper for the `Parties Being Served` component-->
<template v-slot:title>
<slot></slot>
</template>
</base-card>
</ul>
</div>
</template>
<script>
export default {
data() {
return {
selectedComponent: 'base-card',
additionalInfoList : [],
clearForm: false,
counter: 0
}
},
computed : {
additionalInfoListComputed(){
console.log('state changed');
return this.additionalInfoList;
}
},
methods: {
updateAdditionalInfoList(additionalInfo){
this.additionalInfoList.push(additionalInfo);
this.counter++;
console.log('The length is'+this.additionalInfoList.length);
},
deleteParty(resId){
const resIndex = this.additionalInfoList.findIndex(
res => res.id === resId
);
this.additionalInfoList.splice(resIndex, 1);
console.log('Index is '+resIndex);
console.log(this.additionalInfoList);
}
}
}
</script>
<style scoped>
ul{
align-content: left;
padding: 0
}
</style>
BaseCard.vue
<template>
--something
</template>
<script>
import { EventBus } from './bus.js';
export default {
emits:['add-parties','delete-party'],
data() {
return {
additionalInfo:
{
id: new Date().toISOString(),
fullName: '',
preAuthorize: '',
serviceAddress: ''
},
validation: {
fullNameIsValid: true,
serviceAddressIsValid: true
},
hideAddButton: false,
formIsValid: true,
addServiceButtonText: '+ Add Service Notes (Optional)',
serviceNotes: [],
showServiceNotes: false,
showDeleteButton: true,
enteredServiceNote: '', //service notes addendum
}
},
computed : {
showServiceNotex(){
if(!this.showServiceNotes){
return '+Add Service Notes (Optional)'
}else{
return '- Remove Service Notes';
}
}
},
methods: {
setServiceNotes(){
this.showServiceNotes = !this.showServiceNotes;
},
addAnotherParty(){
this.validateForm();
if(!this.formIsValid){
return;
}
let emitObj = JSON.parse(JSON.stringify(this.additionalInfo));
this.$emit('add-parties', emitObj); //event
this.hideAddButton = !this.hideAddButton;
console.log(this.hideAddButton);
},
deleteParty(){
this.$emit('delete-party', this.additionalInfo.id);
},
validateForm(){
this.formIsValid = true;
if(this.additionalInfo.fullName === ''){
this.validation.fullNameIsValid = false;
this.formIsValid = false;
}
if(this.additionalInfo.serviceAddress === ''){
this.validation.serviceAddressIsValid = false;
this.formIsValid = false;
}
},
clearValidity(input){
this.validation[input] = true;
},
clearForm(){
this.additionalInfo.fullName = '';
this.additionalInfo.serviceAddress = '';
this.additionalInfo.preAuthorize = false;
}
},
created(){
console.log('created');
console.log(this.hideAddButton);
}
}
</script>
