Transition으로 감쌌는데 애니메이션이 전혀 걸리지 않은 이유
문제 발생
알림 배너에 페이드 효과를 넣으려고 감쌌는데 아무 변화가 없었습니다.
<Transition>
<div class="banner">{{ message }}</div>
</Transition>message만 바꿔서는 아무 일도 일어나지 않았고, CSS도 어디에 써야 할지 알 수 없었습니다.
원인 분석
두 가지가 빠져 있습니다.
첫째, 발동 조건입니다. Vue 문서는 <Transition>이 요소나 컴포넌트가 DOM에 들어오고 나갈 때 애니메이션을 적용한다고 설명하고, 그 계기를 넷으로 나열합니다 — v-if에 의한 조건부 렌더, v-show에 의한 조건부 표시, <component>의 동적 컴포넌트 전환, 그리고 특별한 key 속성의 변경입니다. 텍스트만 바뀌는 것은 그 어느 것도 아니라 상태 변화가 감지되지 않습니다.
둘째, 클래스입니다. Vue는 진입·퇴장 각각에 세 개씩, 총 여섯 개의 클래스를 적절한 시점에 붙였다 뗍니다 — v-enter-from, v-enter-active, v-enter-to, v-leave-from, v-leave-active, v-leave-to. 실제 애니메이션은 우리가 이 클래스들에 CSS를 써야 일어납니다.
구조 제약도 있습니다 — <Transition>은 슬롯 내용으로 단일 요소나 컴포넌트만 지원하며, 컴포넌트라면 그 컴포넌트도 단일 루트 요소를 가져야 합니다.
해결 방안
- 발동 조건을 만듭니다. 내용이 바뀔 때 전환하려면
key를 붙입니다.
<Transition name="fade">
<div class="banner" :key="message">{{ message }}</div>
</Transition>- CSS를 여섯 클래스에 맞춰 씁니다.
name을 주면 접두사가 바뀝니다.
.fade-enter-active, .fade-leave-active { transition: opacity 0.25s ease; }
.fade-enter-from, .fade-leave-to { opacity: 0; }-
단일 루트를 지킵니다. 컴포넌트를 감쌀 때 그 컴포넌트가 여러 루트 노드를 반환하면 전환이 적용되지 않습니다.
-
목록에는
<TransitionGroup>을 씁니다. 여러 항목의 진입·퇴장·이동은 별개 컴포넌트의 일이고,key가 필수입니다. -
동작 최소화 설정을 존중합니다.
prefers-reduced-motion에서 전환 시간을 0에 가깝게 낮춥니다 — 이 저장소의 접근성 원칙이기도 합니다. -
JS 훅은 필요할 때만 씁니다.
@enter,@leave훅으로 세밀하게 제어할 수 있지만, CSS로 되는 것을 JS로 옮기면 유지보수 비용만 늘어납니다.
댓글0
댓글을 남기려면 로그인이 필요해요. 로그인
아직 댓글이 없어요. 첫 의견을 편하게 남겨 보세요.