Transition은 엘리먼트가 DOM에 들어오거나 나갈 때 애니메이션을 적용하는 Vue의 내장 컴포넌트입니다.

면접에서 직접 물어보는 경우는 드물지만, 포트폴리오에서 부드러운 전환을 구현했다면 UX 감각을 보여줄 수 있는 좋은 포인트입니다.


Transition 기본

VUE
<script setup lang="ts">
import { ref } from 'vue'
const show = ref(true)
</script>

<template>
  <button @click="show = !show">토글</button>

  <Transition name="fade">
    <p v-if="show">안녕하세요!</p>
  </Transition>
</template>

<style>
/* 진입 애니메이션 */
.fade-enter-active {
  transition: opacity 0.3s ease;
}

/* 퇴장 애니메이션 */
.fade-leave-active {
  transition: opacity 0.3s ease;
}

/* 진입 시작 상태 / 퇴장 종료 상태 */
.fade-enter-from,
.fade-leave-to {
  opacity: 0;
}
</style>

CSS 클래스 흐름

PLAINTEXT
진입: enter-from → enter-active → enter-to
퇴장: leave-from → leave-active → leave-to
클래스적용 시점제거 시점
v-enter-from삽입 전삽입 후 1프레임
v-enter-active삽입 전전환 완료
v-enter-to삽입 후 1프레임전환 완료
v-leave-from퇴장 시작퇴장 후 1프레임
v-leave-active퇴장 시작전환 완료
v-leave-to퇴장 후 1프레임전환 완료

전환 모드 (mode)

VUE
<template>
  <!-- out-in: 현재 엘리먼트가 나간 후 새 엘리먼트가 들어옴 -->
  <Transition name="fade" mode="out-in">
    <component :is="currentComponent" :key="currentKey" />
  </Transition>

  <!-- in-out: 새 엘리먼트가 들어온 후 현재 엘리먼트가 나감 -->
  <Transition name="fade" mode="in-out">
    <component :is="currentComponent" :key="currentKey" />
  </Transition>
</template>

CSS 애니메이션 (@keyframes)

VUE
<template>
  <Transition name="bounce">
    <p v-if="show">바운스 애니메이션!</p>
  </Transition>
</template>

<style>
.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); }
}
</style>

JavaScript Hooks

CSS 대신 JavaScript로 애니메이션을 제어할 수 있습니다.

VUE
<template>
  <Transition
    @before-enter="onBeforeEnter"
    @enter="onEnter"
    @after-enter="onAfterEnter"
    @before-leave="onBeforeLeave"
    @leave="onLeave"
    @after-leave="onAfterLeave"
    :css="false"
  >
    <div v-if="show">JS 애니메이션</div>
  </Transition>
</template>

<script setup lang="ts">
const onEnter = (el: Element, done: () => void) => {
  const element = el as HTMLElement
  element.style.opacity = '0'

  // Web Animation API 또는 GSAP 등 사용
  element.animate(
    [{ opacity: 0 }, { opacity: 1 }],
    { duration: 300, easing: 'ease-out' }
  ).onfinish = done
}

const onLeave = (el: Element, done: () => void) => {
  const element = el as HTMLElement
  element.animate(
    [{ opacity: 1 }, { opacity: 0 }],
    { duration: 300, easing: 'ease-in' }
  ).onfinish = done
}
</script>

TransitionGroup — 리스트 전환

VUE
<script setup lang="ts">
import { ref } from 'vue'

const items = ref([1, 2, 3, 4, 5])
let nextId = 6

const addItem = () => {
  const index = Math.floor(Math.random() * items.value.length)
  items.value.splice(index, 0, nextId++)
}

const removeItem = (item: number) => {
  items.value = items.value.filter(i => i !== item)
}
</script>

<template>
  <button @click="addItem">추가</button>

  <TransitionGroup name="list" tag="ul">
    <li v-for="item in items" :key="item" @click="removeItem(item)">
      {{ item }}
    </li>
  </TransitionGroup>
</template>

<style>
.list-enter-active,
.list-leave-active {
  transition: all 0.5s ease;
}

.list-enter-from,
.list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

/* FLIP 애니메이션 — 이동하는 아이템도 부드럽게 */
.list-move {
  transition: transform 0.5s ease;
}

/* 떠나는 아이템이 공간을 차지하지 않도록 */
.list-leave-active {
  position: absolute;
}
</style>

appear — 초기 렌더링 시 전환

VUE
<template>
  <!-- 컴포넌트가 처음 렌더링될 때도 전환 적용 -->
  <Transition name="fade" appear>
    <div>처음부터 페이드인</div>
  </Transition>
</template>

면접 팁

  • TransitionGroup의 **FLIP 기법 **(First, Last, Invert, Play)을 알고 있으면 애니메이션 성능에 대한 이해도를 보여줄 수 있습니다
  • mode="out-in"은 ** 컴포넌트 전환에서 깜빡임을 방지 **하는 가장 일반적인 패턴입니다
  • CSS transformopacity만 애니메이션하는 것이 성능에 좋습니다 (GPU 가속)

요약

Transition은 단일 엘리먼트의 진입/퇴장을, TransitionGroup은 리스트의 추가/제거/이동을 애니메이션합니다. CSS transition/animation 또는 JavaScript hooks로 구현하며, mode와 appear 옵션으로 전환 동작을 제어합니다.

댓글 로딩 중...