[Vuejs]-VueJS- Rendering form in a v-for loop that references an initially empty array of objects

2👍

The keys in your v-for should be an id, not an index. Vue ties each component to its key.

With keys, it will reorder elements based on the order change of keys, and elements with keys that are no longer present will always be removed/destroyed.

vue documentation

When you splice the partyInfoList item, Vue reregisters the indexes. The indexes cascade down, and since the there are now 2 items in partyInfoList instead of 3, the Vue component with an index of 2, or the last component, gets removed.

Here is an example:

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

    // index: 1
    {
        id: 1,
        fullName: 'second',
        serviceAddress: '2',
        preAuthorize: ''
    },

    // index: 2
    {
        id: 2,
        fullName: 'third',
        serviceAddress: '3',
        preAuthorize: ''
    },
]

Splice

// resId = 1
this.partiesInfoList.splice(resId, 1);

Resulting array

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

    // index: 1
    {
        id: 2,
        fullName: 'third',
        serviceAddress: '3',
        preAuthorize: ''
    },
]

The array looks fine, but templates on the screen do not. This is because Vue saw that the partyInfoList item with an index of 2 does not exist anymore, so the component with :key="2" and all of its data was removed the DOM.

Your solution is actually very simple. All you need to do is change :key="index" to :key="data.id". This will tie your component to the data, not a dynamic value like an index.

I also don’t know how you are setting the id on each partyInfoList item, but those must be unique for the keys to work.

This is what your new code should look like:

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

1👍

In updatePartiesInfoList just before pushing new object to partiesInfoList, check if this.partiesInfoList[0].fullName === 'dummy' returns true, then if the condition is truthy, execute this.partiesInfoList.splice(0, 1) to remove the dummy object from your array!

Leave a comment