CSS-переходы во Vue.js реализуются с помощью встроенного компонента
<transition>, который позволяет добавлять анимацию
при появлении, исчезновении или смене состояния элементов. Компонент
оборачивает целевой элемент и автоматически управляет добавлением и
удалением CSS-классов в соответствии с жизненным циклом элемента.
<template>
<transition name="fade">
<p v-if="show">Пример текста с переходом</p>
</transition>
</template>
<script>
export default {
data() {
return {
show: true
}
}
}
</script>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
.fade-enter-to, .fade-leave-from {
opacity: 1;
}
</style>
Ключевые моменты:
v-if управляет наличием элемента в DOM, инициируя
переход.*-enter-* и *-leave-* применяются
автоматически.*-active определяет длительность и свойства анимации
через transition.Vue разделяет процесс анимации на четыре класса:
v-enter-from — начальное состояние элемента при
появлении.v-enter-to — конечное состояние элемента при завершении
анимации появления.v-leave-from — начальное состояние элемента при
исчезновении.v-leave-to — конечное состояние элемента при завершении
анимации исчезновения.Пример с масштабированием:
<template>
<transition name="scale">
<div v-if="visible" class="box"></div>
</transition>
</template>
<script>
export default {
data() {
return {
visible: false
}
}
}
</script>
<style>
.scale-enter-active, .scale-leave-active {
transition: transform 0.3s ease;
}
.scale-enter-from, .scale-leave-to {
transform: scale(0);
}
.scale-enter-to, .scale-leave-from {
transform: scale(1);
}
.box {
width: 100px;
height: 100px;
background-color: #42b983;
}
</style>
Атрибут name компонента <transition>
автоматически добавляет префикс к классам. Для более гибкого контроля
доступны следующие атрибуты:
appear — включает анимацию при
первоначальном рендере элемента.mode — определяет последовательность
анимации для нескольких элементов (in-out,
out-in).<transition name="fade" appear mode="out-in">
<p v-if="show">Текст с появлением и уходом</p>
</transition>
Режимы анимации:
in-out: новый элемент сначала появляется, затем старый
исчезает.out-in: старый элемент исчезает полностью, после чего
появляется новый.Для анимации списков используется
<transition-group>. Он добавляет анимацию при
добавлении, удалении и перемещении элементов.
<template>
<transition-group name="list" tag="ul">
<li v-for="item in items" :key="item.id">{{ item.text }}</li>
</transition-group>
</template>
<script>
export default {
data() {
return {
items: [
{ id: 1, text: 'Элемент 1' },
{ id: 2, text: 'Элемент 2' }
]
}
}
}
</script>
<style>
.list-enter-active, .list-leave-active {
transition: all 0.4s ease;
}
.list-enter-from, .list-leave-to {
opacity: 0;
transform: translateY(20px);
}
.list-enter-to, .list-leave-from {
opacity: 1;
transform: translateY(0);
}
</style>
Особенности:
tag позволяет указать контейнер для группы
элементов.key для
корректного отслеживания.Помимо CSS, Vue позволяет управлять переходами через
JavaScript-хуки: before-enter,
enter, after-enter, before-leave,
leave, after-leave. Они дают полный контроль
над анимацией и интеграцию с библиотеками типа GSAP или anime.js.
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter">
<div v-if="show" class="box"></div>
</transition>
<script>
export default {
methods: {
beforeEnter(el) {
el.style.opacity = 0;
},
enter(el, done) {
gsap.to(el, { opacity: 1, duration: 0.5, onComplete: done });
},
afterEnter(el) {
console.log('Анимация завершена');
}
}
}
</script>
Преимущества использования хуков:
Часто используется сочетание CSS и JS-переходов. CSS управляет простыми анимациями (например, fade, scale), а JS-хуки выполняют более сложные эффекты или синхронизацию с внешними библиотеками.
<transition
name="fade-scale"
v-on:enter="animateEnter"
v-on:leave="animateLeave">
<div v-if="active" class="box"></div>
</transition>
<script>
export default {
methods: {
animateEnter(el, done) {
el.style.transform = 'scale(0)';
gsap.to(el, { scale: 1, opacity: 1, duration: 0.4, onComplete: done });
},
animateLeave(el, done) {
gsap.to(el, { scale: 0, opacity: 0, duration: 0.4, onComplete: done });
}
}
}
</script>
<style>
.fade-scale-enter-active, .fade-scale-leave-active {
transition: opacity 0.4s ease;
}
.fade-scale-enter-from, .fade-scale-leave-to {
opacity: 0;
}
.fade-scale-enter-to, .fade-scale-leave-from {
opacity: 1;
}
</style>
Такой подход обеспечивает плавность визуальных эффектов, сохраняя управляемость через Vue и расширяемость с использованием JavaScript.
transform и opacity, так как
они GPU-ускоренные.width,
height, margin), чтобы избежать reflow.key, чтобы Vue правильно
отслеживал элементы и использовал переходы эффективно.