Vue 내장 컴포넌트 Transition, Teleport 사용법
Transition 컴포넌트
DOM 또는 컴포넌트가 추가/제거될 때 애니메이션을 적용하는 트랜지션 컴포넌트입니다.
v-if, v-show, 동적 컴포넌트 등 조건부 렌더링되는 단일 자식 요소에 효과가 적용됩니다.
Transition 컴포넌트 클래스 종류
v-enter-from | 요소가 나타나기 시작할 때 적용되는 클래스 |
v-enter-active | 요소가 나타나는 동안 적용되는 트랜지션 (애니메이션) 클래스 |
v-enter-to | 요소가 나타난 후 적용되는 클래스 |
v-leave-from | 요소가 사라지기 시작할 때 적용되는 클래스 |
v-leave-active | 요소가 사라지는 동안 적용되는 트랜지션 (애니메이션) 클래스 |
v-leave-to | 요소가 사라진 후 적용되는 클래스 |
부드러운 Transition 효과
<template>
<Transition>
<div v-if="isShow">애니메이션 효과 적용 테스트</div>
</Transition>
</template>
<script setup>
import { ref } from 'vue';
const isShow = ref(true);
</script>
<style scoped>
.v-enter-from {
opacity: 0;
}
.v-enter-active {
transition: opacity 0.5s ease;
}
.v-enter-to {
opacity: 1;
}
.v-leave-from {
opacity: 1;
}
.v-leave-active {
transition: opacity 0.5s ease;
}
.v-leave-to {
opacity: 0;
}
</style>
Transition 컴포넌트 내부 요소가 나타날 때, 투명도 0부터 1로 0.5초간 변하는 애니메이션 효과를 부여합니다.
요소가 사라질 때는 투명도 1부터 0으로 0.5초간 변하는 애니메이션 효과를 부여합니다.
서서히 나타나고, 서서히 사라지는 부드러운 Transition 효과 예시입니다.
Named Transitions 예시
<template>
<Transition name="애니메이션명">
<div v-if="isShow">슬라이드 애니메이션 테스트</div>
</Transition>
</template>
<script setup>
import { ref } from 'vue';
const isShow = ref(true);
</script>
<style scoped>
.애니메이션명-enter-from,
.애니메이션명-leave-to {
opacity: 0;
transform: translateY(-30px);
}
.애니메이션명-enter-active,
.애니메이션명-leave-active {
transition: all 0.5s ease; // opacity, transform 모두 적용
}
.애니메이션명-enter-to,
.애니메이션명-leave-from {
opacity: 1;
transform: translateY(0px);
}
</style>
Transition 컴포넌트 내부 요소가 나타날 때, 위에서 아래로 내려오는 슬라이드 애니메이션도 적용하였습니다.
요소가 사라질 때는 아래에서 위로 사라지는 애니메이션 효과를 부여합니다.
TransitionGroup 컴포넌트
리스트 등 여러 자식 요소가 추가/제거/순서 변경될 때 각각 애니메이션을 적용해주는 컴포넌트입니다.
TransitionGroup 컴포넌트 사용
<template>
<TransitionGroup name="애니메이션명">
<div v-for="({ message, type }, index) in items" :key="index" class="alert" :class="alertStyle(type)">
<div/>
</TransitionGroup>
</template>
<script setup>
defineProps({
items: Array, // 파라미터 객체 배열
});
const alertStyle = type => (type === 'error' ? 'alert-danger' : 'alert-primary');
</script>
<style scoped>
.애니메이션명-enter-from,
.애니메이션명-leave-to {
opacity: 0;
transform: translateY(-30px);
}
.애니메이션명-enter-active,
.애니메이션명-leave-active {
transition: all 0.5s ease; // opacity, transform 모두 적용
}
.애니메이션명-enter-to,
.애니메이션명-leave-from {
opacity: 1;
transform: translateY(0px);
}
</style>
TransitionGroup 컴포넌트 내부 요소들에 각각 애니메이션을 적용합니다.
alert Array 추가 및 삭제
<template>
<하위컴포넌트 :items="alerts"></하위컴포넌트>
</template>
<script setup>
const alerts = ref([]);
// alert 추가 및 삭제 공통함수
const vAlert = (message, type = 'error') => {
// alert 객체 추가
alerts.value.push({ message, type });
// alert 추가 2초 뒤, alerts 목록에서 첫 번째 요소 제거
setTimeout(() => {
alerts.value.shift();
});
};
</script>
TransitionGroup 컴포넌트가 있는 컴포넌트의 부모컴포넌트 코드입니다.
Teleport 컴포넌트
현재 컴포넌트가 아닌 다른 위치에 요소를 렌더링할 수 있는 텔레포트 컴포넌트입니다.
모달, 툴팁, 드롭다운 등 부모컴포넌트 외부에 렌더링되어야 하는 UI 요소를 만들 때 사용합니다.
Vue 모달 팝업 텔레포트
// 모달 호출하는 자식컴포넌트 예시
<Teleport to="#modal">
<모달컴포넌트명 v-model="show" :data변수명="data변수명">
</모달컴포넌트명>
</Teleport>
// index.html 또는 부모컴포넌트 예시
<div id="modal"></div>
모달이 특정 컴포넌트 내부에 속해서 CSS가 깨질 때, 상위 DOM 위치에 렌더링하여 해결할 수 있습니다.
헤더, 푸터, 전역 로딩 스피너, 모달, 알림, 초기 앱 설정 등은 App.Vue에 정의하는 것이 좋습니다.