JavaScript анимации

Vue.js предоставляет мощные и гибкие возможности для работы с анимациями, позволяя интегрировать как простые переходы, так и сложные анимационные эффекты, используя встроенные директивы и сторонние библиотеки. Основой для анимаций является компонент <transition> и <transition-group>. Эти компоненты не рендерят лишний HTML, а просто оборачивают содержимое, которое подлежит анимации.

<template>
  <transition name="fade">
    <p v-if="show">Привет, Vue!</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;
}
</style>

В примере используется стандартный паттерн *-enter-active, *-enter-from, *-leave-active и *-leave-to, который позволяет управлять фазами появления и исчезновения элемента.

Переходы между состояниями

Vue.js поддерживает CSS-переходы и JavaScript-хуки для более сложных сценариев. CSS-переходы выполняются автоматически, если указаны соответствующие классы. Для более точного контроля можно использовать хуки:

<transition
  @before-enter="beforeEnter"
  @enter="enter"
  @leave="leave"
>
  <div v-if="visible">Анимация через JS</div>
</transition>

<script>
export default {
  data() {
    return { visible: true };
  },
  methods: {
    beforeEnter(el) {
      el.style.opacity = 0;
    },
    enter(el, done) {
      gsap.to(el, { opacity: 1, duration: 0.5, onComplete: done });
    },
    leave(el, done) {
      gsap.to(el, { opacity: 0, duration: 0.5, onComplete: done });
    }
  }
};
</script>

Использование JavaScript-анимаций позволяет интегрировать библиотеки вроде GSAP или Anime.js для сложных эффектов, сохраняя реактивность компонентов.

Анимация списков с <transition-group>

Для анимации динамических списков используется <transition-group>. Он позволяет анимировать добавление, удаление и перестановку элементов в DOM.

<transition-group name="list" tag="ul">
  <li v-for="item in items" :key="item.id">{{ item.text }}</li>
</transition-group>

<style>
.list-enter-active, .list-leave-active {
  transition: all 0.5s;
}
.list-enter-from, .list-leave-to {
  transform: translateY(30px);
  opacity: 0;
}
</style>

Ключевой момент — уникальный key для каждого элемента, без которого Vue не сможет правильно отследить изменения и применить анимацию.

Управление состоянием анимаций

Vue позволяет использовать динамические классы для изменения анимаций в зависимости от состояния компонента. Например:

<transition :name="animationName">
  <div v-if="showBox">Контент</div>
</transition>

<script>
export default {
  data() {
    return {
      showBox: true,
      animationName: 'fade'
    };
  }
};
</script>

Таким образом, можно переключать тип анимации на лету, изменяя свойство animationName.

Использование сторонних библиотек

Для сложных анимаций с физическими эффектами или временными кривыми используют сторонние библиотеки:

  • GSAP — мощная библиотека с таймлайнами, кривыми, анимацией SVG.
  • Anime.js — легкая библиотека для комплексных переходов и работы с DOM.
  • Velocity.js — высокопроизводительная альтернатива jQuery-анимациям.

Vue обеспечивает интеграцию через хуки <transition> и v-if, что позволяет полностью контролировать жизненный цикл анимаций.

Параллельные и последовательные анимации

Для последовательной анимации нескольких элементов применяется mode="out-in" или mode="in-out":

<transition name="fade" mode="out-in">
  <component :is="currentComponent"></component>
</transition>
  • out-in — текущий элемент полностью исчезает перед появлением нового.
  • in-out — новый элемент появляется перед исчезновением старого.

Для параллельных анимаций достаточно использовать стандартные CSS или JS-анимации без изменения режима.

Рекомендации по производительности

  • Минимизировать использование тяжелых CSS-свойств (box-shadow, filter) для плавности.
  • Для длинных списков использовать v-show вместо v-if, когда элемент часто скрывается и показывается.
  • Для сложных последовательностей применять JS-анимации с таймлайнами вместо чистого CSS.

Интерактивные анимации

Vue позволяет связывать анимации с событиями пользователя:

<div @mouseenter="hover = true" @mouseleave="hover = false">
  <transition name="scale">
    <div v-if="hover">Наведи на меня</div>
  </transition>
</div>

<style>
.scale-enter-active, .scale-leave-active {
  transition: transform 0.3s;
}
.scale-enter-from, .scale-leave-to {
  transform: scale(0);
}
</style>

Это позволяет создавать динамичные интерфейсы, реагирующие на действия пользователя, без сложного управления DOM напрямую.

Анимация маршрутов

При работе с vue-router анимации применяются к компонентам маршрутов с помощью <transition> вокруг <router-view>:

<transition name="route" mode="out-in">
  <router-view></router-view>
</transition>

<style>
.route-enter-active, .route-leave-active {
  transition: opacity 0.5s;
}
.route-enter-from, .route-leave-to {
  opacity: 0;
}
</style>

Комбинация с mode="out-in" обеспечивает плавное переключение между страницами приложения.


Анимации во Vue.js строятся на сочетании реактивности, CSS-переходов и JavaScript-хуков, что позволяет создавать как простые визуальные эффекты, так и сложные интерактивные интерфейсы с минимальным количеством кода.