Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/14.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 尽管使用了唯一键,但v-for在使用阵列拼接时删除了错误的元素_Javascript_Arrays_Vue.js_Vue Component_V For - Fatal编程技术网

Javascript 尽管使用了唯一键,但v-for在使用阵列拼接时删除了错误的元素

Javascript 尽管使用了唯一键,但v-for在使用阵列拼接时删除了错误的元素,javascript,arrays,vue.js,vue-component,v-for,Javascript,Arrays,Vue.js,Vue Component,V For,我目前正在使用v-for打印“参与方”元素列表,其中每个“参与方”由表示。当我在表示“参与方”数组的附加信息列表上使用splice()并在控制台上记录输出时,我发现已从数组中删除了正确的元素。但是,当我观察屏幕上的输出时,Vue设法从列表中删除数组的最后一个元素或相邻元素。基于各种建议和研究,我使用了独特的:key来帮助Vue,但它仍然给了我这个有害的bug BaseCardList.vue <template> <div> <ul>

我目前正在使用
v-for
打印“参与方”元素列表,其中每个“参与方”由
表示。当我在表示“参与方”数组的
附加信息列表上使用
splice()
并在控制台上记录输出时,我发现已从数组中删除了正确的元素。但是,当我观察屏幕上的输出时,Vue设法从列表中删除数组的最后一个元素或相邻元素。基于各种建议和研究,我使用了独特的
:key
来帮助Vue,但它仍然给了我这个有害的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>  
<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>

导出默认值{ 数据(){ 返回{ selectedComponent:'基本卡', 附加信息列表:[], clearForm:false, 柜台:0 } }, 计算:{ additionalInfoListComputed(){ log('state changed'); 返回此.additionalInfoList; } }, 方法:{ UpdateAdditionalInvolist(附加信息){ this.additionalInfoList.push(additionalInfo); 这个.counter++; log('长度为'+this.additionalInfoList.length); }, 删除方(剩余){ const resIndex=this.additionalInfoList.findIndex( res=>res.id==resId ); 此.additionalInfoList.splice(resIndex,1); log('索引为'+resIndex); console.log(this.additionalInfoList); } } } 保险商实验室{ 对齐内容:左对齐; 填充:0 }
BaseCard.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>  
<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>

--某物
从'/bus.js'导入{EventBus};
导出默认值{
发出:[“添加方”、“删除方”],
数据(){
返回{
其他信息:
{
id:new Date().toISOString(),
全名:“”,
预授权:'',
服务地址:“”
},
验证:{
fullNameIsValid:true,
serviceAddressIsValid:true
},
隐藏按钮:false,
福米斯瓦利德:是的,
addServiceButtonText:“+添加服务说明(可选)”,
服务说明:[],
showServiceNotes:false,
showDeleteButton:true,
enteredServiceNote:“”,//服务说明附录
}
},
计算:{
showServiceNotex(){
如果(!this.showServiceNotes){
返回“+添加维修说明(可选)”
}否则{
返回“-删除维修注释”;
}
}
},
方法:{
setServiceNotes(){
this.showServiceNotes=!this.showServiceNotes;
},
另一方{
这是validateForm();
如果(!this.formIsValid){
返回;
}
让emitObj=JSON.parse(JSON.stringify(this.additionalInfo));
此.emit('add-parties',emitObj);//事件
this.hideAddButton=!this.hideAddButton;
console.log(this.hideAddButton);
},
删除方(){
此.emit('delete-party',this.additionalInfo.id);
},
validateForm(){
this.formIsValid=true;
如果(this.additionalInfo.fullName==''){
this.validation.fullNameIsValid=false;
this.formIsValid=false;
}
如果(this.additionalInfo.serviceAddress==''){
this.validation.serviceAddressIsValid=false;
this.formIsValid=false;
}
},
clearValidity(输入){
this.validation[input]=true;
},
clearForm(){
this.additionalInfo.fullName='';
this.additionalInfo.serviceAddress='';
this.additionalInfo.preAuthorize=false;
}
},
创建(){
console.log('created');
console.log(this.hideAddButton);
}
}
输出屏幕

您应该将索引传递给delete方法
deleteParty

<base-card v-for="(data,index) in additionalInfoListComputed" :key="JSON.stringify(data.id)" ref="childComponent"
  @add-parties="updateAdditionalInfoList" @delete-party="deleteParty(index)">
  <!-- Wrapper for the `Parties Being Served` component-->
  <template v-slot:title>

    <slot></slot>
  </template>
</base-card>

在子组件中生成ID的代码可能会创建重复的ID。在速度足够快的机器上,所有ID都将相同:

id: new Date().toISOString()
删除它并使用真正独特的东西,比如基于
v-for
索引的东西