Хуки жизненного цикла
Каждый компонент проходит этапы: создание, вывод на страницу (монтирование), обновления и удаление (размонтирование). Хуки жизненного цикла — функции, через которые вы просите Vue выполнить код на определённом этапе, например запустить таймер, когда компонент появился, и остановить его, когда компонент исчез.
Хук onMounted
onMounted вызывается, когда элементы компонента уже добавлены в DOM:
<!-- src/components/TodoHeader.vue -->
<script setup>
import { onMounted } from 'vue'
console.log('setup: компонент создаётся')
onMounted(() => {
console.log('mounted: компонент на странице')
})
</script>
<template>
<h1>Мои задачи</h1>
</template>В консоли браузера появятся две строки в таком порядке: сначала setup, затем mounted. Код верхнего уровня <script setup> выполняется до вывода на страницу, поэтому элементов DOM там ещё нет.
Основные хуки
| Хук | Когда вызывается | Для чего |
|---|---|---|
onMounted | Компонент выведен на страницу | Работа с DOM, загрузка данных, подписки |
onUpdated | После перерисовки из-за изменения данных | Редко: чтение размеров DOM |
onBeforeUnmount | Перед удалением | Сохранить что-то, пока DOM ещё есть |
onUnmounted | Компонент удалён | Остановить таймеры, снять обработчики |
Все хуки импортируются из vue и вызываются синхронно в <script setup>.
Таймер с очисткой
Часы в шапке списка задач — пример, где нужны два хука:
<!-- src/components/TodoClock.vue -->
<script setup>
import { ref, onMounted, onUnmounted } from 'vue'
const time = ref(new Date().toLocaleTimeString())
let timerId
onMounted(() => {
timerId = setInterval(() => {
time.value = new Date().toLocaleTimeString()
}, 1000)
})
onUnmounted(() => {
clearInterval(timerId)
})
</script>
<template>
<p>Сейчас {{ time }}</p>
</template>Подключите компонент в App.vue строкой <TodoClock v-if="showClock" /> — часы будут тикать каждую секунду. Когда showClock станет false, компонент удалится, и onUnmounted остановит таймер.
Обработчики на window
Так же снимают обработчики, повешенные на window или document:
<script setup>
import { onMounted, onUnmounted } from 'vue'
function onKey(event) {
if (event.key === 'Escape') console.log('Закрыть')
}
onMounted(() => window.addEventListener('keydown', onKey))
onUnmounted(() => window.removeEventListener('keydown', onKey))
</script>Пока компонент на странице, нажатие Escape пишет в консоль «Закрыть».
Частая ошибка
Не остановить таймер или не снять обработчик в onUnmounted. Компонент исчезает со страницы, но setInterval продолжает работать. Если компонент показывают и скрывают несколько раз, таймеров становится всё больше: страница тормозит, а в консоли появляются повторяющиеся сообщения. Всё, что запущено в onMounted, останавливайте в onUnmounted.