логотип PurpleSchool
логотип PurpleSchool

Использование хуков жизненного цикла Vue для управления состоянием компонента

Автор

Олег Марков

Введение

Работа с состоянием компонента — одна из основ разработки на Vue. Важно не только инициировать данные в нужный момент, но и правильно очищать ресурсы, реагировать на изменения данных, асинхронно загружать информацию. Всё это становится возможным с помощью хуков жизненного цикла компонента во Vue. Эти хуки представляют собой специальные методы, автоматически вызываемые на разных этапах жизни компонента — от его создания до уничтожения. Они позволяют гибко управлять поведением, работой с API, подписками на события и состоянием.

В этой статье вы узнаете:

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

Рассматривать будем оба подхода: Options API и Composition API, чтобы вы могли выбрать наиболее удобный вариант.

Жизненный цикл компонента Vue — обзор

Во Vue жизненный цикл компонента — это последовательность стадий, через которые проходит каждый компонент: создание, монтирование в DOM, обновление и уничтожение. На каждом этапе вы можете «вклиниться» с помощью специальных методов. Посмотрим, как выглядит этот цикл в общих чертах:

  • Инициализация (Initialization)
  • Монтирование (Mounting)
  • Обновление (Updating)
  • Размонтирование/уничтожение (Unmounting/Destruction)

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

Вот стандартные хуки жизненного цикла во Vue (на примере Options API):

  • beforeCreate — до инициализации данных и событий.
  • created — после инициализации данных, событий, но до монтирования.
  • beforeMount — перед вставкой в DOM.
  • mounted — после первой вставки в DOM.
  • beforeUpdate — перед тем, как реактивные данные вызовут повторный render.
  • updated — после обновления DOM.
  • beforeUnmount — перед удалением компонента из DOM (Vue 3).
  • unmounted — когда компонент полностью уничтожен (Vue 3).

Начиная с Vue 3, появились составные хуки (Composition API), такие как onMounted, onUpdated и другие, которые используются напрямую внутри функций.

Разбор основных хуков с примерами

Инициализация: beforeCreate и created

Первые два хука позволяют выполнять операции при старте жизни компонента.

Определение начального состояния

export default {
  data() {
    return {
      message: '', // здесь мы определяем начальное состояние
    }
  },
  beforeCreate() {
    // Срабатывает до инициализации state
    // Здесь this.message еще не доступен!
    // Обычно здесь редко что-то делают
  },
  created() {
    // Срабатывает после инициализации state и событий
    // this.message уже доступен
    this.message = 'Привет, Vue!';
    // Здесь часто делают начальные асинхронные запросы к API
    // или инициализацию глобальных слушателей
  }
}

Вам стоит помнить: на этапе beforeCreate нельзя обращаться к данным, а вот в created — уже можно и даже хорошо начинать загрузку данных.

Загрузка данных асинхронно

export default {
  data() {
    return {
      user: null,
    }
  },
  async created() {
    // Здесь делаем запрос к серверу
    const r = await fetch('/api/user');
    this.user = await r.json();
    // Теперь user будет обновлен и отрисован в шаблоне
  }
}

Обратите внимание: любые изменения состояния здесь автоматически отображаются на UI.

Монтирование: beforeMount и mounted

Когда компонент уже готовится к появлению в DOM, срабатывает beforeMount, но чаще всего используется mounted. Здесь хорошо делать инициализацию работы с внешними библиотеками, подписками на события, DOM-операции.

Пример: инициализация сторонней библиотеки

export default {
  mounted() {
    // Здесь элемент уже в DOM, можно обращаться к $refs
    this.chart = new Chart(this.$refs.chartCanvas, {
      // опции графика
    });
    // Теперь вы можете обновлять this.chart при изменении данных компонента
  }
}

DOM-элементы, объявленные через ref, становятся доступны только с этого момента.

Обновление: beforeUpdate и updated

Эти хуки срабатывают при каждом изменении реактивных данных, вызывающем ререндер компонента.

export default {
  data() {
    return { count: 0 }
  },
  beforeUpdate() {
    // Можно сравнить старое и новое состояние перед обновлением view
    console.log('Перед обновлением, count:', this.count);
  },
  updated() {
    // Выполняется после обновления DOM
    // Обычно здесь можно взаимодействовать с уже обновленным DOM
    console.log('DOM обновлен, текущее значение count:', this.count);
  }
}

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

Уничтожение: beforeUnmount и unmounted (Vue 3)

Очень важные хуки! Здесь стоит очищать таймеры, отписываться от глобальных событий и чистить все сторонние ресурсы.

export default {
  mounted() {
    this.timer = setInterval(() => {
      this.message = `Время: ${new Date().toLocaleTimeString()}`
    }, 1000)
  },
  beforeUnmount() {
    // Таймеры нужно очищать!
    clearInterval(this.timer)
  },
  unmounted() {
    // Здесь дополнительных действий по очистке чаще всего не требуется.
    // Можно делать финальный лог или удалять сторонние объекты.
    this.timer = null
  }
}

Если забыть очистить ресурсы, могут «утечь» память и возникнуть неожиданные побочные эффекты.

Использование хуков жизненного цикла в Composition API

В современном Vue (начиная с версии 3) для более гибкого и модульного подхода появился Composition API. Хуки объявляются через функции вроде onMounted, onUnmounted прямо внутри функции setup.

Пример минимального компонента с хуками Composition API

<template>
  <div>Счетчик: {{ count }}</div>
</template>

<script setup>
import { ref, onMounted, onUpdated, onUnmounted } from 'vue'

const count = ref(0)
let timer = null

onMounted(() => {
  // Запускаем обновление счетчика каждую секунду
  timer = setInterval(() => {
    count.value++
  }, 1000)
})

onUpdated(() => {
  // Можно реагировать на обновление компонента
  console.log('Компонент обновился, count:', count.value)
})

onUnmounted(() => {
  // Очищаем таймер
  clearInterval(timer)
})
</script>

В Composition API важно помнить:

  • ref используется для реактивных данных,
  • все хуки объявляют внутри функции setup или с помощью <script setup>, если пишете SFC.

Как взаимодействовать с состоянием

Любые изменения переменных, объявленных через ref или reactive, автоматически запускают обновление компонента и соответствующие хуки жизненного цикла.

import { ref, onMounted } from 'vue'

export default {
  setup() {
    const user = ref(null)

    onMounted(async () => {
      const res = await fetch('/api/user')
      user.value = await res.json()
    })

    return { user }
  }
}

Смотрите, вы получаете ту же гибкость, что и в Options API, но ваш код теперь становится легко масштабируемым и повторно используемым.

Совмещённые хуки и кастомные функции

В Composition API можно создавать свои собственные хуки, объединяя логику жизненного цикла и работы с состоянием:

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

function useClock() {
  const time = ref(new Date())
  let timer = null

  onMounted(() => {
    timer = setInterval(() => {
      time.value = new Date()
    }, 1000)
  })
  onUnmounted(() => {
    clearInterval(timer)
  })
  return { time }
}

export default {
  setup() {
    const { time } = useClock()
    return { time }
  }
}

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

Практические советы при управлении состоянием через хуки

  • Всегда очищайте асинхронные операции, таймеры, подписки в хуках уничтожения, иначе могут возникнуть утечки памяти.
  • Не полагайтесь на порядок срабатывания хуков без причины — проектируйте логику, опираясь на специфику задачи.
  • В хуках обновления (updated, onUpdated) изменяйте только внешний (не реактивный) контент или работайте с неуправляемыми DOM-элементами.
  • Для загрузки данных используйте created (Options API) или onMounted (Composition API).
  • Помните, что хуки работают только на уровне самого компонента — чтобы гарантировать правильную работу при переходах между страницами, используйте также навигационные события в роутерах при необходимости.

Пример — интеграция с API и автоматическое обновление

Допустим, вам нужно загружать пользователей при создании компонента, раз в 30 секунд обновлять список и очищать таймер при удалении компонента. Покажу пример на Composition API:

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

export default {
  setup() {
    const users = ref([])
    let timer = null

    async function fetchUsers() {
      const res = await fetch('/api/users')
      users.value = await res.json()
    }

    onMounted(() => {
      fetchUsers()
      timer = setInterval(fetchUsers, 30000) // обновлять каждые 30 секунд
    })

    onUnmounted(() => {
      clearInterval(timer)
    })

    return { users }
  }
}

Посмотрите, как просто реализовать сразу и асинхронную загрузку, и очистку ресурсов.

Хуки жизненного цикла во Vue 2 и Vue 3 — отличия

В Vue 2 и Vue 3 названия большинства хуков совпадают, но некоторые отличаются:

  • События beforeDestroy и destroyed в Vue 2 были переименованы на beforeUnmount и unmounted в Vue 3.
  • Хуки для Composition API (onMounted и др.) появились только в Vue 3, в Vue 2 оперировать можно только методом Options API.
  • Специфика работы с контекстом this: в Composition API все делаетесь внутри функции setup, где this уже не нужен, используете возвращаемые переменные напрямую.

Если мигрируете на Vue 3 — просто замените хуки, используйте новые имена и бросайте взгляд в документацию.

Заключение

Использование хуков жизненного цикла во Vue — один из самых эффективных способов контролировать состояние компонентов на всех стадиях их жизни. От старта до завершения работы они позволяют вам:

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

Выбирайте между Options API и Composition API в зависимости от требований проекта или предпочтений вашего коллектива. В любом случае — вы получаете удобные инструменты для написания поддерживаемых и предсказуемых компонентов.

Частозадаваемые технические вопросы по теме статьи и ответы на них

Как можно использовать хуки жизненного цикла во Vue 2 с синтаксисом Composition API?

В Vue 2 нельзя использовать хуки onMounted, onUnmounted напрямую, но вы можете подключить официальную библиотеку @vue/composition-api и применять аналогичный синтаксис, как в Vue 3: js import { onMounted } from '@vue/composition-api' // Далее используйте onMounted внутри функции setup

Могу ли я вызвать хук жизненного цикла вручную?

Нет, хуки жизненного цикла Vue вызываются только внутренними механизмами фреймворка. Если нужна ваша кастомная логика — создайте обычную функцию и вызывайте при необходимости.

Как правильно очищать сторонние события и подписки?

Очищайте слушатели событий, таймеры и подписки в хуке уничтожения: beforeUnmount/unmounted (Vue 3) или beforeDestroy/destroyed (Vue 2). Всегда храните ссылки на подписки или идентификаторы таймеров, чтобы потом их использовать для снятия.

Можно ли управлять несколькими независимыми состояниями в одном компоненте с помощью хуков?

Да, каждый раз, когда вы объявляете новое состояние через ref или reactive, компоненты будут реактивно реагировать на изменения, а хуки работать для всего компонента. Для изоляции логики удобно выносить её в кастомные функции/хуки.

Как работать с асинхронными действиями в хуках жизненного цикла?

В большинстве хуков (created, mounted, onMounted) можно объявлять функции async или возвращать Promise. Главное — не забыть обрабатывать возможные ошибки и очищать асинхронные операции при уничтожении компонента.

Стрелочка влевоИспользование метода map в Vue для обработки массивовРабота с ключами key в списках и компонентах VueСтрелочка вправо

Все гайды по Vue

Руководство по валидации форм во Vue.jsИнтеграция Tiptap для создания редакторов на VueРабота с таблицами во Vue через TanStackИнструкция по установке и компонентам Vue sliderУправление пакетами Vue js с помощью npmУправление пакетами и node modules в Vue проектахКак использовать meta для улучшения SEO на VueПолный гайд по компоненту messages во Vuejs5 правил использования Inertia с Vue и LaravelИнструкция по работе с grid на VueРабота с модулями и пакетами в VueGithub для Vue проектов - подробная инструкция по хранению и совместной работеНастройка ESLint для Vue проектов и поддержка качества кодаОбработка ошибок и отладка в Vue.jsИспользование Vue Devtools для отладки и мониторинга приложенийРабота с конфигурационными файлами и скриптами VueСоздание и настройка проектов Vue с помощью Vue CLI3 способа интеграции Chart.js с Vue для создания графиковРабота с Canvas во VueИнструкция по реализации календаря во VueРабота с Ant Design Vue для создания UI на Vue
Обзор и использование утилит Vue для удобной разработкиРабота с обновлениями компонента и жизненным циклом updateРазрешение конфликтов и ошибок с помощью Vue resolveЗагрузка и управление состоянием загрузки в VueИспользование query-параметров и их обработка в маршрутах VueИспользование библиотек Vue для расширения функционалаРабота с JSON данными в приложениях VueКак работать с экземплярами компонента Instance во VueПолучение данных и API-запросы во Vue.jsЭкспорт и импорт данных и компонентов в VueОбработка событий и их передача между компонентами VuejsГайд по defineEmits на Vue 3Понимание core функционала Vue и его применениеПонимание и применение Composition API в Vue 3Понимание и работа с компилятором VueКогда и как использовать $emit и call во VueВзаимодействие с внешними API через Axios в Vue
Веб приложения на Vue архитектура и лучшие практикиИспользование Vite для быстрого старта и сборки проектов на Vue 3Работа с URL и ссылками в приложениях на VueРабота с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueИспользование Quasar Framework для разработки на Vue с готовыми UI-компонентамиОбзор популярных шаблонов и стартовых проектов на VueИнтеграция Vue с PHP для создания динамичных веб-приложенийКак организовать страницы и маршруты в проекте на VueNuxt JS и Vue 3 для SSR приложенийСоздание серверных приложений на Vue с помощью Nuxt jsИспользование Vue Native для разработки мобильных приложенийОрганизация и управление индексной страницей в проектах VueИспользование Docker для контейнеризации приложений на VueИнтеграция Vue.js с Django для создания полноценных веб-приложенийСоздание и работа с дистрибутивом build dist Vue приложенийРабота со стилями и CSS в Vue js для красивых интерфейсовСоздание и структурирование Vue.js приложенияКак исправить ошибку cannot find module vueНастройка и сборка проектов Vue с использованием современных инструментовИнтеграция Vue с Bitrix для корпоративных решенийРазработка административных панелей на Vue js
Интеграция Tailwind CSS с Vue для современных интерфейсов5 библиотек для создания tree view во VueИнтеграция Vue с серверной частью и HTTPS настройкамиКак обрабатывать async операции с Promise во VueИнтеграция Node.js и Vue.js для разработки приложенийРуководство по интеграции Vue js в NET проектыПримеры использования JSX во VueГайд по импорту и регистрации компонентов на VueМногоязычные приложения на Vue с i18nИнтеграция FLIR данных с Vue5 примеров использования filter во Vue для упрощения разработки3 примера реализации drag-and-drop во Vue
Управление переменными и реактивными свойствами во VueИспользование v for и slot в VueПрименение v-bind для динамической привязки атрибутов в VueУправление пользователями и их данными в Vue приложенияхСоздание и использование UI Kit для Vue приложенийТипизация и использование TypeScript в VuejsИспользование шаблонов в Vue js для построения интерфейсовИспользование Swiper для создания слайдеров в VueРабота со стилями и стилизацией в VueСтруктура и особенности Single File Components SFC в VueРабота со SCSS в проектах на Vue для стилизацииРабота со скроллингом и прокруткой в Vue приложенияхПрименение script setup синтаксиса в Vue 3 для упрощения компонентовИспользование scoped стилей для изоляции CSS в компонентах Vue3 способа улучшить навигацию Vue с push()Обработка запросов и асинхронных операций в VueПонимание и использование provide inject для передачи данных между компонентамиПередача и использование props в Vue 3 для взаимодействия компонентовУправление property и функциями во Vue.jsПередача данных между компонентами с помощью props в Vue jsРабота со свойствами компонентов VueУправление параметрами и динамическими данными во VueРабота с lifecycle-хуком onMounted во VueОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование модальных окон modal в Vue приложенияхИспользование методов в компонентах Vue для обработки логикиИспользование метода map в Vue для обработки массивовИспользование хуков жизненного цикла Vue для управления состоянием компонентаРабота с ключами key в списках и компонентах VueОбработка пользовательского ввода в Vue.jsРабота с изображениями и их оптимизация в VueИспользование хуков жизненного цикла в VueОрганизация сеток и гридов для верстки интерфейсов на VueСоздание и управление формами в VueОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emitРабота с динамическими компонентами и данными в Vue3 способа манипулирования DOM на VueРуководство по div во VueИспользование директив в Vue и их расширенные возможностиОсновы и применение директив в VueИспользование директив и их особенности на Vue с помощью defineИспользование компонентов datepicker в Vue для выбора датОрганизация циклов и итераций во VueКак работает компиляция Vue CoreСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в VueИспользование классов в Vue для организации кода и компонентовИспользование директивы checked для управления состоянием чекбоксов в VueГайд на checkbox компонент во VueСоздание и настройка кнопок в VueОтображение данных в виде графиков с помощью Vue ChartСоздание и настройка кнопок в Vue приложенияхРабота с lifecycle-хуками beforeCreate и beforeMount во VueИспользование массивов и методов их обработки в VueИспользование массивов и их обработка в Vue
Использование Vuetify для создания современных интерфейсов на VueИспользование transition во VueТестирование компонентов и приложений на VueРабота с teleport для управления DOM во VueПять шагов по настройке SSR в VuejsИспользование Shadcn UI компонентов с Vue для продвинутых интерфейсовИспользование router-link для навигации в Vue RouterКак использовать require в Vue для динамического импорта модулейРабота с динамическим рендерингом и виртуальным DOM на Vue.jsИспользование ref для управления ссылками и реактивностью в Vue 3Использование Vue Pro и его преимущества для профессиональной разработкиРуководство по nextTick для работы с DOMСоздание и использование компонентов с помощью Vue js и CУправление состоянием и реактивностью через inject и provideДинамическое обновление компонентов и данных на VueГлубокое изучение документации Vue и как эффективно её использоватьИспользование Crystal с Vue для разработкиИспользование вычисляемых свойств для динамического отображения данных на Vue jsОптимизация производительности и предупреждения в Vue
Открыть базу знаний