Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/382.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 VueJS—v-for循环中的呈现形式,该循环引用最初为空的对象数组_Javascript_Arrays_Vue.js_Dom_V For - Fatal编程技术网

Javascript VueJS—v-for循环中的呈现形式,该循环引用最初为空的对象数组

Javascript VueJS—v-for循环中的呈现形式,该循环引用最初为空的对象数组,javascript,arrays,vue.js,dom,v-for,Javascript,Arrays,Vue.js,Dom,V For,问题陈述: 我正在尝试一种设计,它涉及复制每个添加按钮上的被服务方表单字段。单击Add按钮,相应的PartyInfo对象将添加到PartyInfoList数组中 在BaseButtonList.vue文件中,我使用PartyInfoList数组来设置v-for循环 <base-card v-for="(data, index) of partiesInfoList" :key="index" ref=

问题陈述: 我正在尝试一种设计,它涉及复制每个
添加按钮上的
被服务方
表单字段。单击
Add按钮
,相应的
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"
            >
附加的是
,它在
v-for
循环中呈现表单元素

BaseCardList.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>
<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>

从“./BaseCard.vue”导入BaseCard; 导出默认值{ 组件:{BaseCard}, 数据(){ 返回{ selectedComponent:'基本卡', PartiesInfo列表:[ {id:0, 全名:'dummy', serviceAddress:'虚拟', 预授权:“” } ], clearForm:false, 柜台:1 } }, 计算:{ hasParty(){ 返回this.partiesInfo.length>0; }, partiesInfo列表长度(){ 返回this.partiesInfo.length; } }, 方法:{ UpdatePartiesInfo列表(附加信息){ //如果(this.counter==0){ //这个.partiesInfoList.splice(0,1); // } this.partiesInfo.push(additionalInfo); 这个.counter++; console.log(this.partiesInfo列表); log('列表的长度为'+this.partiesInfo.length'); }, 删除方(剩余){ //const resIndex=this.partiesInfo.findIndex( //res=>res.id==resId // ); //此.partiesInfo.splice(resIndex,1); if(this.counter==1){ 返回; } 这个.partiesInfoList.splice(resId,1); console.log('索引为'+resId'); console.log('del'之后); console.log(this.partiesInfo列表); } } }
屏幕上的实际输出错误:从DOM中删除相邻元素。比如说,我点击“第二个”的“删除”,但“第三个”被删除。但是,如果在v-for的末尾有一个空表单元素,那么这个元素就会被删除。

更新PartiesInfo列表
中,在将新对象推送到
PartiesInfo列表
之前,检查
这个.PartiesInfo列表[0]。全名==='dummy'
返回
true
,然后如果条件为true,则执行
这个.partiesInfo列表。拼接(0,1)
以从数组中删除虚拟对象

在将新对象推送到
partiesInfoList
之前,在
更新partiesInfoList
中,检查是否
此项。partiesInfoList[0]。fullName=='dummy'
返回
true
,然后如果条件为true,则执行
此.partiesInfoList.splice(0,1)
以从数组中删除虚拟对象

您的
v-for
中的键应该是id,而不是索引。Vue将每个组件与其键绑定

对于键,它将根据键的顺序更改对元素进行重新排序,并且具有不再存在的键的元素将始终被删除/销毁

拼接
partyFolist
项目时,Vue会重新注册索引。索引向下级联,由于
partyFolist
中现在有2个项目而不是3个,因此索引为
2
的Vue组件或最后一个组件将被删除

以下是一个例子: 拼接

// resId = 1
this.partiesInfoList.splice(resId, 1);
结果数组

// partyInfoList
[
    // index: 0
    {
        id: 0,
        fullName: 'first',
        serviceAddress: '1',
        preAuthorize: ''
    },

    // index: 1
    {
        id: 2,
        fullName: 'third',
        serviceAddress: '3',
        preAuthorize: ''
    },
]
阵列看起来很好,但屏幕上的模板却不行。这是因为Vue发现索引为
2
PartyFolist
项已不存在,因此带有
:key=“2”
的组件及其所有数据已从DOM中删除

你的解决方案其实很简单。您只需将
:key=“index”
更改为
:key=“data.id”
。这会将组件绑定到数据,而不是像索引那样的动态值

我也不知道您如何在每个
partyInfoList
项上设置
id
,但这些项必须是唯一的,才能使键工作

这就是您的新代码的外观:

<base-card
        v-for="(data, index) of partiesInfoList" :key="data.id"
        ref="childComponent"
        @add-parties="updatePartiesInfoList"
        @delete-party="deleteParty(index)"
        :lastElement="index ===  partiesInfoListLength - 1"
        >

您的
v-for
中的键应该是id,而不是索引。Vue将每个组件与其键绑定

对于键,它将根据键的顺序更改对元素进行重新排序,并且具有不再存在的键的元素将始终被删除/销毁

拼接
partyFolist
项目时,Vue会重新注册索引。索引向下级联,由于
partyFolist
中现在有2个项目而不是3个,因此索引为
2
的Vue组件或最后一个组件将被删除

以下是一个例子: 拼接

// resId = 1
this.partiesInfoList.splice(resId, 1);
结果数组

// partyInfoList
[
    // index: 0
    {
        id: 0,
        fullName: 'first',
        serviceAddress: '1',
        preAuthorize: ''
    },

    // index: 1
    {
        id: 2,
        fullName: 'third',
        serviceAddress: '3',
        preAuthorize: ''
    },
]
阵列看起来很好,但屏幕上的模板却不行。这是因为Vue发现索引为
2
PartyFolist
项已不存在,因此带有
:key=“2”
的组件及其所有数据已从DOM中删除

你的解决方案其实很简单。您只需将
:key=“index”
更改为
:key=“data.id”
。这会将组件绑定到数据,而不是像索引那样的动态值

我也不知道您如何在每个
partyInfoList
项上设置
id
,但这些项必须是唯一的,才能使键工作

这就是您的新代码的外观:

<base-card
        v-for="(data, index) of partiesInfoList" :key="data.id"
        ref="childComponent"
        @add-parties="updatePartiesInfoList"
        @delete-party="deleteParty(index)"
        :lastElement="index ===  partiesInfoListLength - 1"
        >