Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

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

Каждый компонент проходит этапы: создание, вывод на страницу (монтирование), обновления и удаление (размонтирование). Хуки жизненного цикла — функции, через которые вы просите 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.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.