Vue có sẵn một component để chuyên làm animation là <transition/>
<transition>
<component />
</transition>
Nó sẽ thêm một số CSS class, mà dựa vào đó chúng ta có thể thêm animation cho component.
v-enter
: state ban đầu, được thêm vào trước khi element được chèn vào DOM, remove ngay sau frame insertv-enter-active
: được thêm vào trước lúc insert remove sau khi animation kết thúc, tồn tại trong suốt lúc enter. Có thể dùng để define duration, delay, easing cho transition enterv-enter-to
: có từ version 2.1.8. Add sau 1 frame khi element đã insert, cùng lúc vớiv-enter
bị xóa, xóa sau khi animation kết thúc.v-leave
: thêm vào ngay lúc có transition leaving, remove sau đó 1 framev-leave-active
: sẽ có trong lúc leaving. Tương tự v-enter-activev-leave-to
: tương tự v-enter-to
Nếu không thích thêm v-
vào trước mấy class này, chúng ta có thể define một cái prefix khác.
<transition name='my-transition' />
Để thêm giá trị duration
trên component (tính theo mili giây)
<transition :duration="1000" />
<transition :duration="{ enter: 500, leave: 800 }"/>
Ví dụ 1: làm dropdown menu
<li class="dropdown">
<button class="dropbtn" @mouseover="show = true" @mouseout="show = false">Dropdown
<i class="down-arrow"></i>
</button>
<transition name="dropdown">
<ul class="dropdown-content" v-if="show" @mouseover="show = true" @mouseout="show = false">
<li><a href="#">Link 1</a></li>
<li><a href="#">Link 2</a></li>
<li><a href="#">Link 3</a></li>
</ul>
</transition>
</li>
Thêm các CSS cần thiết
.dropdown-enter,
.dropdown-leave-to {
transform: scaleY(0.7);
opacity: 0;
}
.dropdown-enter-to,
.dropdown-leave {
opacity: 1;
transform: scaleY(1);
}
.dropdown-enter-active,
.dropdown-leave-active {
transition: all 0.3s ease-out;
transform-origin: top center;
}
Ví dụ 2: làm form flipping
<transition name="card" mode="out-in">
<div class="card" v-if="front == true" key="front">
<h2>Sign In</h2>
<div class="form">
<h1>Sign In Form</h1>
</div>
<div class="footer">
<span>Not a member?</span>
<button @click="front = false">
Join Us
</button>
</div>
</div>
<div class="card" v-else key="back">
<h2>Sign Up</h2>
<div class="form">
<h1>Sign Up Form</h1>
</div>
<div class="footer">
<span>Already a member?</span>
<button @click="front = true">
Log In
</button>
</div>
</div>
</transition>
CSS cần thiết
.card-enter, .card-leave-to {
opacity: 0;
transform: rotateY(90deg);
}
.card-enter-active, .card-leave-active {
transition: all 0.5s;
}
See the Pen Vue Case 2: Flipping Form by Envato Tuts+ (@tutsplus) on CodePen.
Ví dụ 3: modal
HTML
<div id="app">
<div v-bind:class="[isShowing ? blurClass : '', clearClass]">
<p>Lorem ipsum dolor sit amet...</p>
<button @click="toggleShow">Say Hello</button>
</div>
<transition enter-active-class="animated zoomIn"
leave-active-class="animated zoomOut">
<modal v-if="isShowing" class="modal">
<button @click="toggleShow">Close</button>
</modal>
</transition>
</div>
CSS
.clear {
transition: opacity 1s;
}
.blur {
filter: blur(1px);
opacity: 0.5;
}
Ví dụ 4: Todo list
<div>
<input v-model="newItemText" />
<button v-on:click="addNewTodo">Add</button>
<button v-on:click="removeTodo">Remove</button>
<transition-group name="list" tag="ul">
<li v-for="task in tasks" v-bind:key="task" >{{ task }}</li>
</transition-group>
</div>
CSS
.list-enter-active {
animation: add-item 1s;
}
.list-leave-active {
position: absolute;
animation: add-item 1s reverse;
}
.list-move {
transition: transform 1s;
}
@keyframes add-item {
0% {
opacity: 0;
transform: translateX(150px);
}
50% {
opacity: 0.5;
transform: translateX(-10px) skewX(20deg);
}
100% {
opacity: 1;
transform: translateX(0px);
}
}
Initializing...