Жизненный цикл в Composition API

Жизненный цикл компонента определяет последовательность этапов его создания, обновления и уничтожения. В Vue.js Composition API управление жизненным циклом становится более явным через использование специальных хуков, которые вызываются в определённые моменты существования компонента. Понимание этих хуков позволяет контролировать поведение компонентов, оптимизировать производительность и корректно работать с ресурсами, такими как таймеры, подписки и сторонние библиотеки.


Основные хуки жизненного цикла

setup()

setup вызывается до создания экземпляра компонента и является центральной точкой для Composition API. Внутри setup определяются реактивные состояния, вычисляемые свойства и методы. Важно помнить:

  • props доступны как первый аргумент.
  • context (второй аргумент) содержит attrs, slots и emit.
  • В setup нельзя напрямую обращаться к this, так как экземпляр компонента ещё не создан.

Пример:

import { ref, computed } from 'vue';

export default {
  props: {
    initialCount: Number
  },
  setup(props) {
    const count = ref(props.initialCount);
    const doubled = computed(() => count.value * 2);

    function increment() {
      count.value++;
    }

    return { count, doubled, increment };
  }
}

onBeforeMount

Хук вызывается непосредственно перед монтированием компонента в DOM. На этом этапе:

  • DOM ещё недоступен.
  • Можно выполнять подготовительные операции, которые не зависят от реального DOM.

Пример:

import { onBeforeMount } from 'vue';

setup() {
  onBeforeMount(() => {
    console.log('Компонент готовится к монтированию');
  });
}

onMounted

Вызывается после монтирования компонента и доступности его DOM-узлов. Используется для:

  • Инициализации сторонних библиотек, работающих с DOM.
  • Запуска анимаций.
  • Получения ссылок на элементы через ref.

Пример:

import { onMounted, ref } from 'vue';

setup() {
  const element = ref(null);

  onMounted(() => {
    console.log('Компонент смонтирован');
    console.log(element.value); // доступ к DOM-элементу
  });

  return { element };
}

onBeforeUpdate

Вызывается перед обновлением компонента в ответ на изменение реактивных данных. Позволяет:

  • Сохранять состояние перед обновлением.
  • Выполнять подготовительные действия до повторного рендеринга.

Пример:

import { ref, onBeforeUpdate } from 'vue';

setup() {
  const count = ref(0);

  onBeforeUpdate(() => {
    console.log('Компонент собирается обновиться');
  });

  return { count };
}

onUpdated

Вызывается после обновления компонента и обновления DOM. Используется для:

  • Синхронизации стороннего UI с DOM.
  • Выполнения действий после изменений данных, которые повлияли на отображение.

Пример:

import { ref, onUpdated } from 'vue';

setup() {
  const count = ref(0);

  onUpdated(() => {
    console.log('Компонент обновлён');
  });

  return { count };
}

onBeforeUnmount

Хук вызывается перед удалением компонента из DOM. Здесь удобно:

  • Отменять таймеры.
  • Отписываться от событий.
  • Освобождать ресурсы сторонних библиотек.

Пример:

import { onBeforeUnmount } from 'vue';

setup() {
  onBeforeUnmount(() => {
    console.log('Компонент готовится к удалению');
  });
}

onUnmounted

Вызывается после удаления компонента из DOM. Используется для окончательной очистки:

  • Обнуление состояний.
  • Завершение асинхронных операций.
  • Удаление подписок.

Пример:

import { onUnmounted } from 'vue';

setup() {
  const intervalId = setInterval(() => console.log('Тик'), 1000);

  onUnmounted(() => {
    clearInterval(intervalId);
    console.log('Компонент удалён и таймер остановлен');
  });
}

Взаимодействие с реактивностью

Все хуки жизненного цикла тесно связаны с реактивной системой Vue. Внутри setup реактивные переменные и вычисляемые свойства могут использоваться совместно с хуками, что позволяет:

  • Обновлять DOM только при изменении необходимых данных.
  • Избегать лишних рендеров.
  • Локализовать эффекты в пределах конкретного жизненного этапа компонента.

Совместное использование хуков

В Composition API хуки можно комбинировать для создания сложной логики. Например, инициализация API-запросов при монтировании и очистка ресурсов при размонтировании:

import { ref, onMounted, onUnmounted } from 'vue';

setup() {
  const data = ref(null);

  const fetchData = async () => {
    const response = await fetch('https://api.example.com/data');
    data.value = await response.json();
  };

  onMounted(fetchData);

  onUnmounted(() => {
    data.value = null;
  });

  return { data };
}

Хуки жизненного цикла и watchEffect

watchEffect и другие реактивные наблюдатели работают внутри setup, автоматически реагируя на изменения данных. Комбинируя их с хуками жизненного цикла, можно строить сложные реактивные сценарии, гарантируя корректное создание и очистку ресурсов. Например:

import { ref, watchEffect, onUnmounted } from 'vue';

setup() {
  const count = ref(0);

  const stopWatch = watchEffect(() => {
    console.log(`Текущее значение count: ${count.value}`);
  });

  onUnmounted(() => {
    stopWatch(); // остановка наблюдателя при удалении компонента
  });

  return { count };
}

Эта система хуков предоставляет полный контроль над каждым этапом существования компонента, делая код более предсказуемым, чистым и управляемым, особенно при работе с асинхронными операциями и сторонними библиотеками.