В Vue Router компонент <router-view>
служит контейнером для отображения компонентов, соответствующих текущему
маршруту. Для создания плавных переходов между страницами используется
встроенная поддержка Vue Transition и
TransitionGroup. Анимация в RouterView
реализуется через комбинацию transition и динамических
ключей, позволяющих Vue отслеживать смену компонентов.
Для применения простых анимаций достаточно обернуть
<router-view> в компонент
<transition>:
<template>
<transition name="fade" mode="out-in">
<router-view :key="$route.fullPath"></router-view>
</transition>
</template>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
</style>
Пояснения:
name="fade" — базовое имя для классов анимации.mode="out-in" — определяет порядок анимации: текущий
компонент сначала уходит, затем появляется новый.:key="$route.fullPath" — динамический ключ, который
обеспечивает корректную перерисовку при изменении маршрута, предотвращая
повторное использование компонента.Vue поддерживает два основных режима:
<transition name="slide" mode="in-out">
<router-view :key="$route.path"></router-view>
</transition>
Классы для анимации сдвига:
.slide-enter-active, .slide-leave-active {
transition: transform 0.3s ease, opacity 0.3s ease;
}
.slide-enter-from {
transform: translateX(100%);
opacity: 0;
}
.slide-leave-to {
transform: translateX(-100%);
opacity: 0;
}
При работе с вложенными <router-view> необходимо
учитывать несколько уровней переходов. Каждый
<router-view> может иметь собственный
<transition>:
<template>
<div>
<transition name="fade" mode="out-in">
<router-view :key="$route.fullPath"></router-view>
</transition>
<transition name="slide" mode="out-in">
<router-view name="nested" :key="$route.fullPath"></router-view>
</transition>
</div>
</template>
Использование разных name позволяет создавать
независимые анимации для главного и вложенного маршрута.
Для маршрутов с параметрами важно использовать ключ, который учитывает изменение параметров:
<router-view :key="$route.params.id"></router-view>
Без этого ключа Vue будет повторно использовать компонент, и анимация не сработает, так как Vue не считает, что компонент был заменен.
<transition> и
<transition-group>Если требуется анимировать списки или несколько компонентов
одновременно, применяется <transition-group>:
<transition-group name="list" tag="div">
<router-view v-for="item in items" :key="item.id"></router-view>
</transition-group>
Классы анимации для групп:
.list-enter-active, .list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from, .list-leave-to {
opacity: 0;
transform: translateY(20px);
}
При использовании router.push или
router.replace можно отслеживать направление перехода,
чтобы динамически менять анимацию:
<template>
<transition :name="transitionName">
<router-view :key="$route.fullPath"></router-view>
</transition>
</template>
<script>
export default {
data() {
return {
transitionName: 'fade'
}
},
watch: {
'$route'(to, from) {
const toIndex = parseInt(to.meta.index || 0);
const fromIndex = parseInt(from.meta.index || 0);
this.transitionName = toIndex > fromIndex ? 'slide-left' : 'slide-right';
}
}
}
</script>
В этом примере используется meta.index маршрута для
определения направления анимации, что позволяет создавать эффект
навигации «вперед» и «назад», аналогично мобильным приложениям.
Vue Router совместим с CSS-библиотеками анимации (Animate.css, GSAP). Применение GSAP позволяет создавать сложные последовательности переходов:
import { gsap } from "gsap";
export default {
methods: {
enterAnimation(el, done) {
gsap.fromTo(el, { opacity: 0, x: 100 }, { opacity: 1, x: 0, duration: 0.5, onComplete: done });
},
leaveAnimation(el, done) {
gsap.to(el, { opacity: 0, x: -100, duration: 0.5, onComplete: done });
}
}
}
<transition
v-on:enter="enterAnimation"
v-on:leave="leaveAnimation"
mode="out-in"
>
<router-view :key="$route.fullPath"></router-view>
</transition>
Использование JavaScript-хуков <transition> дает
полный контроль над временной шкалой, синхронизацией и сложными
эффектами.
key) для
<router-view> при смене маршрутов.mode="out-in" для корректного
скрытия старого компонента перед показом нового.<transition> с разными именами.