63. Fixing the Animation
npm create vue@latest
이 강의에서는 Vue에서 애니메이션된 리스트의 문제를 해결하는 방법을 다룹니다.
리스트 아이템이 추가될 때나 제거될 때, 다른 아이템들이 부드럽게 이동하도록 하는 것이 목표입니다.
Vue는 move
클래스를 사용하여 이동 중인 아이템들에 대한 애니메이션을 처리합니다.
이 클래스는 fade move
와 같이 사용자가 정의한 전환 이름으로 생성됩니다.
이 클래스를 사용하여 리스트 아이템들이 부드럽게 이동하도록 CSS에서 transition
속성을 적용합니다.
요소가 제거될 때 문제가 발생하는데, 이는 절대 위치를 사용하여 해결할 수 있습니다.
절대 위치를 적용하면 제거되는 요소가 공간을 차지하지 않게 되어, 다른 요소들이 그 공간을 부드럽게 채우게 됩니다.
App.vue
<script setup lang="ts">
import {ref} from "vue";
const numbers = ref([1, 2, 3, 4, 5]);
const addItem = () => {
const num = Math.floor(Math.random() * 100 + 1);
const index = Math.floor(Math.random() * numbers.value.length);
numbers.value.splice(index, 0, num)
}
const removeItem = (index: number) => {
numbers.value.splice(index, 1);
}
</script>
<template>
<button type="button" @click="addItem">Add</button>
<ul>
<TransitionGroup name="fade">
<li v-for="(number, index) in numbers" :key="number" @click="removeItem(index)">
{{ number }}
</li>
</TransitionGroup>
</ul>
</template>
<style>
h2 {
width: 400px;
padding: 20px;
margin: 20px;
}
.fade-enter-from {
opacity: 0;
}
.fade-enter-active {
transition: all 0.25s linear;
}
.fade-leave-to {
transition: all 0.25s linear;
opacity: 0;
}
.fade-move {
transition: all 1s linear;
}
.fade-leave-active {
position: absolute;
}
.zoom-enter-active {
animation: zoom-in 1s linear forwards;
transition: all 2s linear;
}
.zoom-leave-active {
animation: zoom-out 1s linear forwards;
transition: all 2s linear;
}
.zoom-enter-from {
opacity: 0;
}
.zoom-leave-to {
opacity: 0;
}
@keyframes zoom-in {
from {
transform: scale(0, 0);
}
to {
transform: scale(1, 1);
}
}
@keyframes zoom-out {
from {
transform: scale(1, 1);
}
to {
transform: scale(0, 0);
}
}
</style>