Понимание хуков жизненного цикла в Vue.js
Если вы разрабатываете приложения на Vue и задаётесь вопросом, когда загружать данные, освобождать ресурсы или взаимодействовать с DOM, вам необходимо понимать хуки жизненного цикла. Эти хуки являются основой поведения компонентов в Vue 3, однако многие разработчики испытывают трудности с выбором нужного хука и моментом его использования.
В этой статье объясняются хуки жизненного цикла Vue 3 с использованием Composition API, охватывая каждую фазу от создания компонента до его уничтожения, с практическими примерами, которые вы можете применить немедленно.
Ключевые выводы
- Хук setup заменяет как beforeCreate, так и created из Options API Vue 2
- onMounted идеально подходит для операций с DOM и API-вызовов после рендеринга компонента
- Всегда освобождайте ресурсы в onUnmounted для предотвращения утечек памяти
- Хуки жизненного цикла должны вызываться синхронно внутри функции setup
Хук Setup: точка входа вашего компонента
Хук setup является краеугольным камнем Composition API Vue 3, заменяя как beforeCreate, так и created из Vue 2. Он выполняется до полной инициализации экземпляра компонента, что делает его идеальным местом для определения реактивного состояния и композиции логики компонента.
import { ref, reactive } from 'vue'
export default {
setup(props, context) {
const count = ref(0)
const user = reactive({ name: '', email: '' })
// Logic runs immediately, before template compilation
console.log('Component initializing')
return { count, user }
}
}
В отличие от Options API Vue 2, функция setup получает props и context в качестве параметров, предоставляя прямой доступ к свойствам компонента без использования this.
Фаза монтирования: onBeforeMount и onMounted
onBeforeMount() - подготовка перед DOM
Хук onBeforeMount срабатывает после setup, но до создания DOM компонента. Используйте его для операций, которые должны произойти перед рендерингом, но не требуют доступа к DOM.
import { onBeforeMount } from 'vue'
export default {
setup() {
onBeforeMount(() => {
// Initialize non-DOM dependent resources
console.log('Template compiled, DOM not yet created')
})
}
}
onMounted() - операции при готовности DOM
onMounted — это место, где происходит большая часть инициализации, связанной с DOM. Шаблон компонента был отрендерен и вставлен в документ, что делает безопасным доступ к элементам и инициализацию сторонних библиотек.
import { ref, onMounted } from 'vue'
export default {
setup() {
const chartContainer = ref(null)
onMounted(async () => {
// Fetch data after component mounts
const data = await fetch('/api/data').then(r => r.json())
// Initialize chart library with DOM element
// Assuming Chart is imported from a charting library
new Chart(chartContainer.value, { data })
})
return { chartContainer }
}
}
Discover how at OpenReplay.com.
Фаза обновления: изменения реактивного состояния
onBeforeUpdate() - логика перед рендерингом
Когда изменения реактивных данных запускают повторный рендеринг, сначала выполняется onBeforeUpdate. Это ваш последний шанс прочитать текущее состояние DOM до того, как Vue обновит его.
import { onBeforeUpdate } from 'vue'
export default {
setup() {
onBeforeUpdate(() => {
// Capture current scroll position before DOM updates
const scrollY = window.scrollY
// Store or use scrollY as needed
})
}
}
onUpdated() - операции после рендеринга
После того как Vue обновляет DOM, срабатывает onUpdated. Будьте осторожны здесь — изменение реактивного состояния может вызвать бесконечные циклы.
import { onUpdated } from 'vue'
export default {
setup() {
onUpdated(() => {
// DOM has been updated
// Use nextTick() for specific state change reactions
console.log('Component re-rendered')
})
}
}
Фаза размонтирования: очистка компонента
onBeforeUnmount() - задачи перед очисткой
Перед удалением компонента onBeforeUnmount предоставляет доступ к полностью функциональному компоненту в последний раз.
import { onBeforeUnmount, reactive } from 'vue'
export default {
setup() {
const state = reactive({ data: 'important info' })
onBeforeUnmount(() => {
// Save component state or notify external systems
localStorage.setItem('lastState', JSON.stringify(state))
})
return { state }
}
}
onUnmounted() - освобождение ресурсов
onUnmounted критически важен для предотвращения утечек памяти. Здесь следует очищать обработчики событий, таймеры и подписки.
import { onMounted, onUnmounted } from 'vue'
export default {
setup() {
let timer
const handleResize = () => {
console.log('Window resized')
}
onMounted(() => {
timer = setInterval(() => {
console.log('Polling...')
}, 1000)
window.addEventListener('resize', handleResize)
})
onUnmounted(() => {
clearInterval(timer)
window.removeEventListener('resize', handleResize)
})
}
}
Практические паттерны и лучшие практики
Помните об этих ключевых моментах при работе с методами жизненного цикла Vue 3:
- Всегда импортируйте хуки из ‘vue’ перед их использованием
- Вызывайте хуки синхронно внутри setup() — не в колбэках или промисах
- Миграция с Vue 2 на Vue 3:
beforeDestroyтеперьonBeforeUnmount,destroyedтеперьonUnmounted - Серверный рендеринг: хуки монтирования и обновления не выполняются при SSR
Для тестирования компонентов с хуками жизненного цикла используйте Vue Test Utils для правильного запуска и проверки поведения хуков.
Заключение
Хуки жизненного цикла Composition API Vue 3 обеспечивают точный контроль над поведением вашего компонента на каждом этапе. Понимая, когда срабатывает каждый хук и какие ресурсы доступны, вы можете писать более чистые и производительные компоненты. Начинайте с setup() для инициализации, используйте onMounted() для операций с DOM и всегда очищайте ресурсы в onUnmounted() для предотвращения утечек памяти.
Часто задаваемые вопросы
Да, вы можете вызывать один и тот же хук жизненного цикла несколько раз в одной функции setup. Vue выполнит их в порядке их регистрации. Это полезно для организации кода по функциям, а не по фазам жизненного цикла.
onMounted выполняется один раз после первого рендеринга компонента в DOM. nextTick ожидает следующего цикла обновления DOM и может использоваться в любом месте вашего кода, а не только в хуках жизненного цикла. Используйте nextTick, когда вам нужно дождаться отражения конкретного реактивного изменения в DOM.
Да, хуки жизненного цикла отлично работают с script setup. Просто импортируйте и вызывайте их напрямую без обёртывания в функцию setup. Синтаксис script setup автоматически обрабатывает контекст setup за вас.
Оборачивайте логику хуков жизненного цикла в блоки try-catch для обработки ошибок. Vue 3 также предоставляет хук onErrorCaptured для перехвата ошибок из дочерних компонентов. Для глобальной обработки ошибок используйте app.config.errorHandler при создании вашего Vue-приложения.
Gain Debugging Superpowers
Unleash the power of session replay to reproduce bugs, track slowdowns and uncover frustrations in your app. Get complete visibility into your frontend with OpenReplay — the most advanced open-source session replay tool for developers. Check our GitHub repo and join the thousands of developers in our community.