VueJS - Transition and Animation
서론
안녕하세요, 미래의 Vue.js 마법사 여러분! ? Vue.js의 매료적인 전이와 애니메이션 세계를 탐험하는 흥미로운 여정을 안내해 드리게 되어 매우 기쁩니다. 컴퓨터 과학을 몇 년 동안 가르쳐온 경험을 바탕으로 말씀드리면, 웹 애플리케이션에 원활한 전이와 인상적인 애니메이션을 추가하는 것은 쿠키에 설탕을 뿌리는 것과 같습니다. 모든 것이 더욱 즐겁습니다!
beginner이신 분들도 걱정하지 마세요. 우리는 기본부터 차근차근 시작하겠습니다. 이 튜토리얼의 끝을 맞아서, 여러분의 친구들이 "와, 이게 어떻게 가능한 거야?"라고 물을 만큼의 애니메이션을 만들 수 있을 것입니다. 그럼 시작해 보겠습니다!
전이(Transition)
전이는 무엇인가요?
웹 개발의 세계에서 전이는 하나의 상태에서 다른 상태로 부드럽게 변하는 것입니다. 불스위치가 갑자기 켜지고 꺼지는 것이 아니라, 점진적으로 밝아지거나 어두워지는 것을 상상해 보세요. 그것이 전이의 본質입니다!
기본 전이 예제
간단한 예제로 시작해 보겠습니다. 클릭할 때 메시지를 보이고 숨기는 부드러운.fade 효과를 만들겠습니다.
<template>
<div>
<button @click="show = !show">Toggle</button>
<transition name="fade">
<p v-if="show">Hello, I'm a transitioning message!</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
}
}
</script>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
이를 해부해 보겠습니다:
- 버튼을 클릭하면
show
변수가 토글됩니다. -
<transition>
컴포넌트는 메시지를 감싸고 있으며,name
속성이 "fade"로 설정되어 있습니다. - 문단에
v-if
디렉티브는show
변수에 따라 보이거나 숨깁니다. -
<style>
섹션에서 우리는 전이 클래스를 정의합니다:
-
.fade-enter-active
와.fade-leave-active
는 전이 시간을 0.5초로 설정합니다. -
.fade-enter
와.fade-leave-to
는 초기와 최종 투명도를 0(보이지 않음)으로 설정합니다.
버튼을 클릭할 때 메시지가 부드럽게 나타나고 사라집니다. 멋진 것 아닌가요?
애니메이션(Animation)
전이와 애니메이션의 차이는 무엇인가요?
전이는 간단한 상태 변화에 좋지만, 애니메이션은 더 복잡하고 다단계의 효과를 제공합니다. 전이가 불스위치를 부드럽게 끄는 것이라면, 애니메이션은 다양한 색상과 패턴으로 이루어진 라이트 쇼와 같습니다!
기본 애니메이션 예제
점점 뛰는 공의 애니메이션을 만들어 보겠습니다:
<template>
<div>
<button @click="show = !show">Bounce!</button>
<transition name="bounce">
<p v-if="show">?</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
}
}
</script>
<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>
이 예제에서:
- 우리는 이전과 같은 버튼 토글 메커니즘을 사용합니다.
-
<transition>
컴포넌트의 이름이 "bounce"으로 설정되어 있습니다. -
<style>
섹션에서 우리는 다음을 정의합니다:
-
.bounce-enter-active
는bounce-in
애니메이션을 적용합니다. -
.bounce-leave-active
는 동일한 애니메이션을 반대로 적용합니다. -
@keyframes
규칙은bounce-in
애니메이션을 정의합니다.
버튼을 클릭할 때 공이 뛰는 효과와 함께 나타나고 사라집니다. 재미있죠?
커스텀 전이 클래스
Vue.js는 우리에게 커스텀 CSS 클래스를 사용할 수 있는 유연성을 제공합니다. 이는 Animate.css와 같은 제3자 CSS 애니메이션 라이브러리를 사용할 때 매우 유용합니다.
다음과 같이 커스텀 클래스를 사용할 수 있습니다:
<template>
<div>
<button @click="show = !show">Animate!</button>
<transition
enter-active-class="animated fadeInDown"
leave-active-class="animated fadeOutUp"
>
<p v-if="show">? To infinity and beyond!</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
}
}
</script>
<style>
/* Animate.css를 가져왔다고 가정합니다 */
</style>
이 예제에서 우리는 Animate.css 클래스를 직접 <transition>
컴포넌트에 적용하고 있습니다. enter-active-class
와 leave-active-class
속성은 들어오고 나가는 애니메이션에 대한 커스텀 클래스를 지정합니다.
명시적 전이 시간
때로는 전이나 애니메이션의 지속 시간을 명시적으로 설정하고 싶을 수 있습니다. Vue.js는 :duration
속성을 사용하여 이를 설정할 수 있습니다:
<template>
<div>
<button @click="show = !show">Slow Motion</button>
<transition :duration="1000">
<p v-if="show">I'm moving in slow motion...</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
}
}
</script>
<style>
.v-enter-active, .v-leave-active {
transition: all 1s;
}
.v-enter, .v-leave-to {
opacity: 0;
transform: translateY(30px);
}
</style>
여기서 우리는 지속 시간을 1000밀리초(1초)로 설정합니다. 또한, 들어오고 나가는 전이에 대해 다른 지속 시간을 설정할 수 있습니다:
<transition :duration="{ enter: 500, leave: 800 }">
<!-- ... -->
</transition>
JavaScript 훅
Vue.js는 전이에 대해 더 많은 제어를 주기 위해 JavaScript 훅을 제공합니다. 이 훅들은 전이의 특정 시점에서 코드를 실행할 수 있게 해줍니다.
다음은 예제입니다:
<template>
<div>
<button @click="show = !show">Animate</button>
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter"
@enter-cancelled="enterCancelled"
@before-leave="beforeLeave"
@leave="leave"
@after-leave="afterLeave"
@leave-cancelled="leaveCancelled"
>
<p v-if="show">? I'm controlled by JavaScript!</p>
</transition>
</div>
</template>
<script>
export default {
data() {
return {
show: false
}
},
methods: {
beforeEnter(el) {
console.log('Before enter');
},
enter(el, done) {
console.log('Enter');
done();
},
afterEnter(el) {
console.log('After enter');
},
enterCancelled(el) {
console.log('Enter cancelled');
},
beforeLeave(el) {
console.log('Before leave');
},
leave(el, done) {
console.log('Leave');
done();
},
afterLeave(el) {
console.log('After leave');
},
leaveCancelled(el) {
console.log('Leave cancelled');
}
}
}
</script>
이 훅들은 전이 과정에서 정확한 제어를 가능하게 합니다. 다른 애니메이션을 트리거하거나 데이터를 업데이트하거나 특정 작업을 수행하는 데 사용할 수 있습니다.
초기 렌더링 시 전이
Vue.js에서는 기본적으로 전이가 요소가 DOM에 삽입되거나 제거될 때만 발생합니다. 하지만 요소가 최초로 렌더링될 때 전이를 적용하고 싶다면 appear
속성을 사용할 수 있습니다:
<template>
<div>
<transition appear>
<p>? I appear with a transition!</p>
</transition>
</div>
</template>
<style>
.v-enter-active {
transition: all .3s ease;
}
.v-enter {
opacity: 0;
transform: translateY(-20px);
}
</style>
appear
속성을 사용하면 요소가 최초로 렌더링될 때 전이가 발생합니다.
컴포넌트 애니메이션
마지막으로, 컴포넌트에도 우리가 논의한 모든 전이 기능을 사용할 수 있습니다!
<template>
<div>
<button @click="toggleComponent">Switch Component</button>
<transition name="fade" mode="out-in">
<component :is="currentComponent"></component>
</transition>
</div>
</template>
<script>
import ComponentA from './ComponentA.vue'
import ComponentB from './ComponentB.vue'
export default {
components: {
ComponentA,
ComponentB
},
data() {
return {
currentComponent: 'ComponentA'
}
},
methods: {
toggleComponent() {
this.currentComponent = this.currentComponent === 'ComponentA' ? 'ComponentB' : 'ComponentA'
}
}
}
</script>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to {
opacity: 0;
}
</style>
이 예제에서 우리는 두 컴포넌트 사이를 전환할 때 fade 전이를 사용하고 있습니다. mode="out-in"
속성은 기존 컴포넌트가 나가는 동안 새로운 컴포넌트가 들어오도록 합니다.
결론
와, 많은 내용을 다루었습니다! 기본 전이에서 복잡한 애니메이션, 커스텀 클래스에서 JavaScript 훅, 그리고 컴포넌트 애니메이션까지. 이 개념을 습득하는 열쇠는 연습입니다. 따라서 이 예제들을 실험해 보고, 다양한 기술을 혼합하고, 가장 중요한 것은 즐겁게 만들어 보세요!
애니메이션과 전이는 Vue.js 애플리케이션을 더욱生动하게 만들 수 있습니다. 그것은 단순히 보기 좋은 것만이 아니라, 사용자 경험을 향상시키고 사용자를 안내하는 데 도움이 됩니다.
계속 탐구하고, 계속 창의하고, 언제든지 Vue.js 마스터가 될 것입니다. 행복한 코딩, 미래의 Vue.js 마스터 여러분! ?✨
Credits: Image by storyset