<Transition>
컴포넌트
빌트인 컴포넌트.
등록하지 않고도 컴포넌트의 템플릿에서 사용할 수 있다.
- 조건
v-if
를 통한 조건부 렌더링v-show
를 통한 조건부 표시- 스페셜 엘리먼트
<component>
를 통해 전환되는 동적 컴포넌트 key
라는 특수한 속성 값 변경
<button @click="show = !show">토글</button>
<Transition>
<p v-if="show">안녕</p>
</Transition>
.v-enter-active,
.v-leave-active {
transition: opacity 0.5s ease;
}
.v-enter-from,
.v-leave-to {
opacity: 0;
}
CSS 기반 트랜지션
트랜지션 이름 지정
<Transition name="fade">
...
</Transition>
.fade-enter-active,
.fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
}
name
prop을 통해 이름을 지정
CSS 애니메이션
<Transition name="bounce">
<p v-if="show" style="text-align: center;">
안녕! 여기에 탄력적인 텍스트가 있어요!
</p>
</Transition>
.bounce-enter-active {
animation: bounce-in 0.5s;
}
.bounce-leave-active {
animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.25);
}
100% {
transform: scale(1);
}
}
커스터마이징
<Transition>
props에 커스텀 트랜지션 클래스를 정의하여 전달할 수 있다.enter-from-class
enter-active-class
enter-to-class
leave-from-class
leave-active-class
leave-to-class
<!-- Animate.css가 페이지에 포함되어 있다고 가정합니다. -->
<Transition
name="custom-classes"
enter-active-class="animate__animated animate__tada"
leave-active-class="animate__animated animate__bounceOutRight"
>
<p v-if="show">안녕</p>
</Transition>
중첩된 트랜지션
<Transition name="nested">
<div v-if="show" class="outer">
<div class="inner">
안녕
</div>
</div>
</Transition>
/* 중첩 엘리먼트를 대상으로 하는 규칙 */
.nested-enter-active .inner,
.nested-leave-active .inner {
transition: all 0.3s ease-in-out;
}
.nested-enter-from .inner,
.nested-leave-to .inner {
transform: translateX(30px);
opacity: 0;
}
JavaScript 훅
<Transition>
컴포넌트의 이벤트를 수신하여 JavaScript로 트랜지션 프로세스에 연결
<Transition
@before-enter="onBeforeEnter"
@enter="onEnter"
@after-enter="onAfterEnter"
@enter-cancelled="onEnterCancelled"
@before-leave="onBeforeLeave"
@leave="onLeave"
@after-leave="onAfterLeave"
@leave-cancelled="onLeaveCancelled"
>
<!-- ... -->
</Transition>
// 엘리먼트가 DOM에 삽입되기 전에 호출됩니다.
// 이것을 사용하여 엘리먼트의 "enter-from" 상태를 설정합니다.
function onBeforeEnter(el) {}
// 엘리먼트가 삽입되고 1 프레임 후 호출됩니다.
// 진입 애니메이션을 시작하는 데 사용합니다.
function onEnter(el, done) {
// CSS와 함께 사용되는 경우, 선택적으로
// 트랜지션 종료를 나타내기 위해 done 콜백을 호출합니다.
done()
}
// 진입 트랜지션이 완료되면 호출됩니다.
function onAfterEnter(el) {}
// 진입 트랜지션 취소가 완료되기 전 호출됩니다.
function onEnterCancelled(el) {}
// 진출 훅 전에 호출됩니다.
// 대부분의 경우 그냥 진출 훅을 사용해야 합니다.
function onBeforeLeave(el) {}
// 진출 트랜지션이 시작될 때 호출됩니다.
// 진출 애니메이션을 시작하는 데 사용합니다.
function onLeave(el, done) {
// CSS와 함께 사용되는 경우, 선택적으로
// 트랜지션 종료를 나타내기 위해 done 콜백을 호출합니다.
done()
}
// 진출 트랜지션이 완료되고,
// 엘리먼트가 DOM에서 제거된 후 호출됩니다.
function onAfterLeave(el) {}
// v-show 트랜지션에서만 사용 가능합니다.
function onLeaveCancelled(el) {}
트랜지션 모드
진출 애니메이션이 완료된 이후 수행하기를 원한다면
<Transition>
에mode
prop을 전달하여 이 동작을 활성화
<Transition mode="out-in">
...
</Transition>
<Transition name="fade" mode="out-in">
<component :is="activeComponent"></component>
</Transition>
- 동적 컴포넌트에서도 사용할 수 있다.
동적 트랜지션
<Transition>
name
과 같은 prop도 동적일 수 있다.
<Transition :name="transitionName">
<!-- ... -->
</Transition>
key 속성을 사용한 트렌지션
트렌지션을 발생시키기 위해 DOM 엘리먼트를 강제로 다시 렌더링해야 할 필요가 있다.
<script setup>
import { ref } from 'vue';
const count = ref(0);
setInterval(() => count.value++, 1000);
</script>
<template>
<Transition>
<span :key="count">{{ count }}</span>
</Transition>
</template>
key
속성을 사용함으로써, Vue는count
가 변경될 때마다 새로운span
엘리먼트를 생성하고Transition
컴포넌트는 두 개의 다른 엘리먼트 사이에서 트렌지션을 할 수 있다.
트랜지션 그룹
<TransitionGroup>
은 목록에서 렌더링되는 엘리먼트 또는 컴포넌트의 삽입, 제거 및 순서 변경을 애니메이션으로 만들기 위해 설계된 빌트인 컴포넌트
- 기본적으로 래퍼 엘리먼트를 렌더링하지 않습니다. 그러나
tag
prop으로 렌더링할 엘리먼트를 지정할 수 있다. - 트랜지션 모드는 더 이상 상호 배타적인 엘리먼트를 사용하지 않기 때문에 사용할 수 없다.
- 내부 엘리먼트는 고유한
key
속성을 필수로 가져야 한다. - CSS 트랜지션 클래스는 그룹/컨테이너 자체가 아닌 목록의 개별 엘리먼트에 적용된다.
진입/진출 트랜지션
<TransitionGroup name="list" tag="ul">
<li v-for="item in items" :key="item">
{{ item }}
</li>
</TransitionGroup>
.list-enter-active,
.list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
transform: translateX(30px);
}
이동 트랜지션
.list-move, /* 움직이는 엘리먼트에 트랜지션 적용 */
.list-enter-active,
.list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {
opacity: 0;
transform: translateX(30px);
}
/* 이동 애니메이션을 올바르게 계산할 수 있도록
레이아웃 흐름에서 나머지 항목을 꺼내기. */
.list-leave-active {
position: absolute;
}
시차가 있는 목록 트랜지션
<TransitionGroup
tag="ul"
:css="false"
@before-enter="onBeforeEnter"
@enter="onEnter"
@leave="onLeave"
>
<li
v-for="(item, index) in computedList"
:key="item.msg"
:data-index="index"
>
{{ item.msg }}
</li>
</TransitionGroup>
function onEnter(el, done) {
gsap.to(el, {
opacity: 1,
height: '1.6em',
delay: el.dataset.index * 0.15,
onComplete: done
})
}
- JavaScript 훅에서
data-
속성을 기반으로 딜레이를 사용하여 엘리먼트에 애니메이션을 적용
공식 메뉴얼: https://ko.vuejs.org/guide/built-ins/transition.html