I've encountered a funny behavior while trying to make an animation for removing elements in a transition-group.
My Transition Group:
<div class="carrinho-items-lista">
<transition-group name="item-carrinho" @before-leave="beforeLeave">
<carrinho-item @remove-item="removeItem" v-for="item in itemsCarrinho" :key="item.id" :item="item"></carrinho-item>
</transition-group>
</div>
My carrinho-item component
<template>
<div class="flex items-center carrinho-item p-2">
<div class="w-4/12">{{ item.descricao }}</div>
<div class="w-3/12">R$ {{ preco }}</div>
<div class="w-2/12"> {{ item.quantidade }}</div>
<div class="w-2/12">R$ {{ total }}</div>
<div class="w-1/12">
<font-awesome-icon @click="$emit('removeItem', item.id)" icon="fa-solid fa-trash" class="text-2xl" title="Remover item do carrinho de compras" />
</div>
</div>
</template>
CSS
.item-carrinho-leave-from {
opacity: 1;
}
.item-carrinho-leave-active {
transition: all 1s ease-in;
}
.item-carrinho-move {
transition: all 1s ease-in;
}
.item-carrinho-leave-to {
opacity: 0;
transform: translateX(-30px);
}
.item-carrinho-leave-active {
position: absolute;
}
When I try to remove an item, the row's width collapse before the animation, as shown below:
I was able to solve this problem by applying the following (source: https://forum.vuejs.org/t/transition-group-leave-transition-w-position-absolute-jumping-to-top-left-flip/12258/12):
methods: {
beforeLeave(el) {
const {marginLeft, marginTop, width, height} = window.getComputedStyle(el);
el.style.left = `${el.offsetLeft - parseFloat(marginLeft, 10)}px`;
el.style.top = `${el.offsetTop - parseFloat(marginTop, 10)}px`;
el.style.width = width;
el.style.height = height;
},
}
Is this how it's supposed to work? Did anyone face the same issue when working with transition-group in Vue 3?