[Vuejs]-Dynamically create, animate and then remove multiple HTML elements in a Vue2 project

4👍

You’re not far from the right structure. The first issue to fix is that your keys cannot be array indexes here. When you remove an item from the array, the <transition-group> won’t be able to distinguish old item 0 from new item 0 and apply the correct effect. I’ve expanded each wound into an object with a (notional) unique ID like so, but of course you could take various approaches:

wounds: [
    { id: 100, hp: 5 },
    { id: 150, hp: 7 },
    { id: 200, hp: 3 },
],

The corresponding HTML is this. I’ve added data-id and removed the parens from the woundEnter call to support the JS below. I’ve also added appear so that any wounds that are already in queue when the group first renders will be handled correctly.

<transition-group appear name="monster-wounds" tag="ul" class="wounds" @after-enter="woundEnter">
    <li v-for="wound in wounds" :key="wound.id" :data-id="wound.id">
        -{{ wound.hp }}
    </li>
</transition-group>

The final step is to have woundEnter take the target argument from the after-enter event and use it to remove a specific wound from the array, not necessarily the first one, to maintain consistency:

woundEnter(target) {
    const index = this.wounds.findIndex((wound) => wound.id == target.dataset.id);
    if (index !== -1) {
        this.wounds.splice(index, 1);
    }
},

Here’s a codepen with everything working together.

👤kdau

Leave a comment