Transition компонент

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

Основные свойства и атрибуты

  • name — задаёт базовое имя CSS-классов анимации. По умолчанию Vue генерирует классы, добавляя префиксы -enter, -enter-active, -leave, -leave-active.
  • appear — если задано, анимация будет применена при первоначальном рендере компонента.
  • type — указывает тип анимации: transition (по умолчанию) или animation для использования CSS-анимаций.
  • mode — определяет порядок появления и исчезновения элементов. Возможные значения: in-out и out-in.

CSS-классы для анимации

Vue автоматически добавляет классы при изменении состояния элемента. Основные классы:

  1. v-enter — применяется в начале входящей анимации.
  2. v-enter-active — активный класс, содержит длительность анимации и свойства перехода.
  3. v-enter-to — конечное состояние входящей анимации.
  4. v-leave — начальное состояние для ухода элемента.
  5. v-leave-active — активный класс при уходе.
  6. v-leave-to — конечное состояние уходящей анимации.

Пример CSS для плавного появления и исчезновения элемента:

.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;
}

Использование <transition> с условным рендерингом

Наиболее распространённый сценарий — обернуть элемент с v-if:

<template>
  <transition name="fade">
    <p v-if="show">Появляющийся текст</p>
  </transition>
  <button @click="show = !show">Переключить</button>
</template>

<script>
export default {
  data() {
    return {
      show: false
    };
  }
};
</script>

При нажатии на кнопку элемент плавно появляется и исчезает благодаря классам fade-enter и fade-leave.

Переходы с JavaScript-хуками

Vue предоставляет возможность полностью управлять анимацией через JavaScript-хуки:

  • before-enter(el) — перед началом анимации входа.
  • enter(el, done) — основной хук входа, done вызывается после завершения анимации.
  • after-enter(el) — после завершения входа.
  • before-leave(el) — перед началом ухода.
  • leave(el, done) — основной хук ухода.
  • after-leave(el) — после завершения ухода.

Пример анимации с Jav * aScript:

<template>
  <transition
    @before-enter="beforeEnter"
    @enter="enter"
    @after-enter="afterEnter"
    @before-leave="beforeLeave"
    @leave="leave"
    @after-leave="afterLeave"
  >
    <div v-if="show">Анимируемый блок</div>
  </transition>
  <button @click="show = !show">Переключить</button>
</template>

<script>
export default {
  data() {
    return { show: false };
  },
  methods: {
    beforeEnter(el) { el.style.opacity = 0; },
    enter(el, done) {
      const animation = el.animate([{ opacity: 0 }, { opacity: 1 }], { duration: 500 });
      animation.finished.then(done);
    },
    afterEnter(el) { el.style.opacity = ''; },
    beforeLeave(el) { el.style.opacity = 1; },
    leave(el, done) {
      const animation = el.animate([{ opacity: 1 }, { opacity: 0 }], { duration: 500 });
      animation.finished.then(done);
    },
    afterLeave(el) { el.style.opacity = ''; }
  }
};
</script>

Использование JS-хуков позволяет гибко управлять анимациями, создавать динамические эффекты и работать с библиотеками анимации.

Переходы с компонентами

Transition работает не только с простыми HTML-элементами, но и с Vue-компонентами. Например, при динамической подгрузке компонентов через v-if или v-show:

<template>
  <transition name="slide-fade" mode="out-in">
    <component :is="currentComponent" />
  </transition>
  <button @click="toggleComponent">Сменить компонент</button>
</template>

<script>
import ComponentA from './ComponentA.vue';
import ComponentB from './ComponentB.vue';

export default {
  data() {
    return { currentComponent: ComponentA };
  },
  methods: {
    toggleComponent() {
      this.currentComponent = this.currentComponent === ComponentA ? ComponentB : ComponentA;
    }
  }
};
</script>

mode="out-in" обеспечивает, что старый компонент сначала уйдёт, а новый появится после завершения ухода.

<transition-group> для списков

Для анимации нескольких элементов используют <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.5s;
}
.list-enter-from, .list-leave-to {
  opacity: 0;
  transform: translateY(30px);
}
</style>

<transition-group> добавляет уникальные идентификаторы каждому элементу через key и обеспечивает корректную анимацию при изменении порядка элементов.

Рекомендации по оптимизации

  • Для сложных анимаций использовать JS-хуки или внешние библиотеки (GSAP, anime.js) для точного контроля.
  • Всегда указывать уникальные ключи при работе с <transition-group> для предотвращения конфликтов.
  • Комбинировать mode и appear для плавного первого рендера компонентов.
  • Минимизировать количество свойств в CSS-переходах, чтобы не снижать производительность.

Transition компонент является мощным инструментом Vue.js для управления визуальными эффектами и улучшения пользовательского опыта без необходимости напрямую работать с DOM или сторонними библиотеками анимации.