【发布时间】:2021-04-03 15:18:00
【问题描述】:
问题陈述:
我正在尝试设计一个涉及在每个Add button 点击上复制Parties Being Served 表单字段的设计。单击Add Button 时,对应的PartyInfo 对象将添加到PartyInfoList 数组中
在 BaseButtonList.vue 文件中,我使用 PartyInfoList 数组来设置 v-for 循环
<base-card
v-for="(data, index) of partiesInfoList" :key="index"
ref="childComponent"
@add-parties="updatePartiesInfoList"
@delete-party="deleteParty(index)"
:lastElement="index === partiesInfoListLength - 1"
>
但是,重要的是要注意最初数组没有元素。但是,由于我没有其他方法可以将数据输入到数组中,尽管partiesInfoList 数组的元素为零,我还是不得不加载表单。我通过使用虚拟数据设置partiesInfoList 来实现这一点。这允许显示初始表单。当Add Another 按钮被点击时,第一个真正的条目将被推送到partiesInfoList 的第二个索引。
但是,当从数组中删除条目时,这会导致严重的问题。当我控制台记录输出时,splice 确实可以正常工作。但是,Vue 最终会从 DOM 中删除错误的元素。
我使用了唯一的index 键,还尝试了其他可能的键,但都产生了相同的有害错误。任何帮助将不胜感激。我认为这是一个非常棘手的设计模式,我可以想到更简单的替代方案,但我想让它成为一个挑战。也许我可以设置更好的数据流之类的。
附上代码
BaseCard.vue
<template>
//contains the template for the input form element
</template>
<script>
import { random } from '@amcharts/amcharts4/.internal/core/utils/String';
import { EventBus } from './bus.js';
export default {
emits:['add-parties','delete-party'],
props:['lastElement'],
data() {
return {
partyInfo:
{
id: '',
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.counter === 0){
this.counter++;
this.lastElement = false;
}
if(!this.formIsValid){
return;
}
let emitObj = JSON.parse(JSON.stringify(this.partyInfo));
this.$emit('add-parties', emitObj); //event
},
deleteParty(){
this.$emit('delete-party');
},
validateForm(){
this.formIsValid = true;
if(this.partyInfo.fullName === ''){
this.validation.fullNameIsValid = false;
this.formIsValid = false;
}
if(this.partyInfo.serviceAddress === ''){
this.validation.serviceAddressIsValid = false;
this.formIsValid = false;
}
},
clearValidity(input){
this.validation[input] = true;
},
clearForm(){
this.partyInfo.fullName = '';
this.partyInfo.serviceAddress = '';
this.partyInfo.preAuthorize = false;
}
},
created(){
console.log('created');
}
}
</script>
附加的是<BaseCardList>,它在v-for 循环中呈现表单元素
BaseCardList.vue
<template>
<ul>
<base-card
v-for="(data, index) of partiesInfoList" :key="index"
ref="childComponent"
@add-parties="updatePartiesInfoList"
@delete-party="deleteParty(index)"
:lastElement="index === partiesInfoListLength - 1"
>
<!-- Wrapper for the `Parties Being Served` component-->
<template v-slot:title>
<slot></slot>
</template>
</base-card>
</ul>
</template>
<script>
import BaseCard from './BaseCard.vue';
export default {
components: { BaseCard },
data() {
return {
selectedComponent: 'base-card',
partiesInfoList : [
{id: 0,
fullName: 'dummy',
serviceAddress: 'dummy',
preAuthorize: ''
}
],
clearForm: false,
counter: 1
}
},
computed : {
hasParty(){
return this.partiesInfoList.length > 0;
},
partiesInfoListLength(){
return this.partiesInfoList.length;
}
},
methods: {
updatePartiesInfoList(additionalInfo){
// if(this.counter == 0){
// this.partiesInfoList.splice(0,1);
// }
this.partiesInfoList.push(additionalInfo);
this.counter++;
console.log(this.partiesInfoList);
console.log('The length of list is '+this.partiesInfoList.length);
},
deleteParty(resId){
// const resIndex = this.partiesInfoList.findIndex(
// res => res.id === resId
// );
// this.partiesInfoList.splice(resIndex, 1);
if(this.counter == 1){
return;
}
this.partiesInfoList.splice(resId, 1);
console.log('Index is '+resId);
console.log('after del');
console.log(this.partiesInfoList);
}
}
}
</script>
屏幕上的实际输出错误:相邻元素从 DOM 中删除。说,我单击“第二”的删除,但“第三”被删除。但是,如果在 v-for 的末尾有一个空的表单元素,那么这个元素就会被删除。
【问题讨论】:
标签: javascript arrays vue.js dom v-for