Перехватчики жизненного цикла
Каждый экземпляр компонента Vue при создании проходит ряд шагов инициализации — например, ему необходимо настроить наблюдение за данными, скомпилировать шаблон, смонтировать экземпляр в DOM и обновить DOM при изменении данных. Попутно он также запускает функции, называемые перехватчиками жизненного цикла, предоставляя пользователям возможность добавлять свой собственный код на определенных этапах.
Options API
- beforeCreate
- created
- beforeMount
- mounted
- beforeUpdate
- updated
- beforeUnmount
- unmounted
- errorCaptured
- renderTracked
- renderTriggered
- activated
- deactivated
Composition API (setup)
- beforeCreate - Не нужен*
- created- Не нужен*
- onBeforeMount
- onMounted
- onBeforeUpdate
- onUpdated
- onBeforeUnmount
- onUnmounted
- onErrorCaptured
- onRenderTracked
- onRenderTriggered
- onActivated
- onDeactivated
Совет
Поскольку setup запускается приблизительно как и хуки beforeCreate и created, то и не требуется их явно определять. Другими словами, любой код для этих хуков можно указать непосредственно в функции setup
Эти функции принимают коллбэк, который будет выполнен при вызове хука компонентом
Регистрация перехватчиков жизненного цикла
Например, перехватчик можно использовать для запуска кода после того, как компонент завершил первоначальный рендеринг и создал узлы DOM:onMounted
Существуют также другие перехватчики, которые будут вызываться на разных этапах жизненного цикла экземпляра, наиболее часто используемые из них: onMounted, onUpdated и onUnmounted
При вызове onMounted Vue автоматически связывает зарегистрированную функцию обратного вызова с текущим активным экземпляром компонента. Для этого необходимо, чтобы эти перехватчики были зарегистрированы синхронно во время установки компонента. Например, не делайте этого
Обратите внимание, что это не означает, что вызов должен быть лексически помещен внутри setup() или script setup. onMounted() можно вызвать во внешней функции, если стек вызовов синхронен и происходит изнутри setup()
Диаграмма жизненного цикла
Options API
Примечание
Все хуки жизненного цикла автоматически привязывают свой контекст this к экземпляру, поэтому есть доступ к локальному состоянию, вычисляемым свойствам и методам. Нельзя использовать стрелочные функции при определении хука жизненного цикла (например, created: () => this.fetchTodos()) Причина в том, что стрелочные функции привязываются к родительскому контексту, поэтому this не будет экземпляром компонента и this.fetchTodos будет неопределён.
# beforeCreate
- Тип: Function
- Вызывается синхронно сразу после инициализации экземпляра, перед установкой наблюдения за данными и механизмов слежения и событий.
# created
- Тип: Function
- Вызывается синхронно после создания экземпляра. На этом этапе экземпляр закончил обработку опций и настроил: наблюдение за данными, вычисляемые свойства, методы, коллбэки методов-наблюдателей и событий. Однако, фаза монтирования ещё не начата и свойство $el на данный момент недоступно.
# beforeMount
- Тип: Function
- Вызывается непосредственно перед началом монтирования: функция render будет вызываться в первый раз.
- Не вызывается при отрисовке на стороне сервера
# mounted
- Тип: Function
- Вызывается после монтирования экземпляра, где элемент, переданный в app.mount, заменяется вновь созданным vm.$el. Если корневой экземпляр примонтирован на элемент документа, то vm.$el также будет элементом документа при вызове mounted
- Обратите внимание: mounted не гарантирует, что все дочерние компоненты будут уже примонтированы. Если необходимо дождаться, пока будут отрисованы все дочерние компоненты, то можно воспользоваться vm.$nextTick внутри mounted
- Не вызывается при отрисовке на стороне сервера.
# beforeUpdate
- Тип: Function
- Вызывается при изменении данных, перед обновлением DOM. В этом хуке удобно получить доступ к существующему DOM перед обновлением, например, чтобы вручную удалить слушатели событий, которые были добавлены.
- Не вызывается при отрисовке на стороне сервера, потому что на стороне сервера выполняется только первоначальная отрисовка
# updated
- Тип: Function
- Вызывается после того, как обновится виртуальный DOM из-за изменений данных.
- DOM компонента уже будет обновлён к моменту вызова этого хука, поэтому здесь можно выполнять операции, связанные с DOM. Тем не менее, старайтесь избегать изменения состояния в этом хуке. Для реагирования на изменения состояния лучше использовать вычисляемые свойства или отслеживание с помощью методов-наблюдателей.
- Обратите внимание: updated не гарантирует, что все дочерние компоненты также были отрисованы повторно. Если необходимо дождаться повторной отрисовки всех дочерних компонентов, можно воспользоваться vm.$nextTick внутри updated
- Не вызывается при отрисовке на стороне сервера
# activated
- Тип: Function
- Вызывается при активации компонента внутри keep-alive
- Не вызывается при отрисовке на стороне сервера
# deactivated
- Тип: Function
- Вызывается после деактивации компонента внутри keep-alive
- Не вызывается при отрисовке на стороне сервера
# beforeUnmount
- Тип: Function
- Вызывается перед размонтированием экземпляра компонента. На этом этапе экземпляр компонента всё ещё полностью работоспособен
- Не вызывается при отрисовке на стороне сервера
# unmounted
- Тип: Function
- Вызывается после того, как экземпляр компонента размонтирован. Когда этот хук вызван, все директивы экземпляра компонента уже отвязаны, слушатели событий удалены, дочерние экземпляры размонтированы.
- Не вызывается при отрисовке на стороне сервера
# errorCaptured
- Тип: (err: Error, instance: Component, info: string) => ?boolean
- Вызывается, когда фиксируется ошибка из любого дочернего компонента. Хук получает три аргумента: ошибку, экземпляр компонента, в котором вызвана ошибка, и строку с информацией, где была зафиксирована ошибка. Хук может возвращать false, чтобы остановить дальнейшее распространение ошибки.
Совет
В этом хуке можно изменять состояние компонента. Однако важно иметь в шаблоне или render-функции условия, которые оборачивают и отделяют другое содержимое при обнаружении ошибки. Иначе компонент может попасть в бесконечный цикл перерисовки.
Правила распространения ошибок
- По умолчанию все ошибки по-прежнему отправляются в глобальный обработчик config.errorHandler, если он был объявлен. Поэтому ошибки можно отправлять в сервис по сбору аналитики из одного места в коде.
- Если существует несколько хуков errorCaptured в цепочке наследования компонента или родительской цепочке, то все они будут вызваны с этой же ошибкой.
- Если сам хук errorCaptured выбрасывает ошибку, то обе ошибки (зафиксированная и выброшенная хуком) отправятся в глобальный обработчик config.errorHandler
- Хук errorCaptured может возвращать false для предотвращения дальнейшего распространения ошибки. Это значит — «ошибка была обработана и её следует игнорировать», что предотвратит вызов других хуков errorCaptured или глобального config.errorHandler для этой ошибки.
# renderTracked
- Тип: (e: DebuggerEvent) => void
- Вызывается при отслеживании перерисовки виртуального DOM. Хук получает в качестве аргумента debugger event. Это событие сообщает, какая операция была отслежена в компоненте, а также целевой объект и ключ этой операции.
Использование:
# renderTriggered
- Тип: (e: DebuggerEvent) => void
- Вызывается при срабатывании перерисовки виртуального DOM. Подобно renderTracked, в качестве аргумента получает debugger event. Это событие сообщает, какая операция вызвала перерисовку, а также целевой объект и ключ этой операции.
Использование:
Composition API
Примечание по использованию
Все API, перечисленные для composition api, должны вызываться синхронно на этапе setup() компонента.
# onMounted()
- Тип: function onMounted(callback: () => void): void
- Регистрирует обратный вызов, который будет вызываться после монтирования компонента.
Компонент считается смонтированным после:
- Все его синхронные дочерние компоненты смонтированы (не включая асинхронные компоненты или компоненты внутри Suspense деревьев).
- Создано собственное DOM-дерево, которое вставлено в родительский контейнер. Обратите внимание, что это гарантирует, что дерево DOM компонента находится в документе, только если корневой контейнер приложения также находится в документе.
Этот хук обычно используется для выполнения побочных эффектов, требующих доступа к отображаемому DOM компонента, или для ограничения кода, связанного с DOM, клиентом в серверном визуализированное приложение.
Этот хук не вызывается во время рендеринга на стороне сервера.
Пример (Доступ к элементу через ссылку на шаблон)
# onUpdated()
- Тип: function onUpdated(callback: () => void): void
- Регистрирует обратный вызов, который будет вызываться после того, как компонент обновит свое дерево DOM из-за реактивного изменения состояния
- Обновленный хук родительского компонента вызывается после хука его дочерних компонентов.
- Этот хук вызывается после любого обновления DOM компонента, которое может быть вызвано различными изменениями состояния, поскольку несколько изменений состояния могут быть объединены в один цикл рендеринга по соображениям производительности. Если вам нужно получить доступ к обновленному DOM после определенного изменения состояния, используйте вместо этого nextTick()
- Этот хук не вызывается во время рендеринга на стороне сервера.
ПРЕДУПРЕЖДЕНИЕ
Не изменяйте состояние компонента в обновленном хуке — это, скорее всего, приведет к бесконечному циклу обновления!
Пример (Доступ к обновленному DOM)
# onUnmounted()
- Тип: function onUnmounted(callback: () => void): void
- Регистрирует обратный вызов, который будет вызываться после размонтирования компонента
Компонент считается размонтированным после:
- Все его дочерние компоненты были размонтированы.
- Все связанные с ним реактивные эффекты (эффект рендеринга и вычисленные/наблюдатели, созданные во время setup()) были остановлены.
Используйте этот крючок для очистки созданных вручную побочных эффектов, таких как таймеры, прослушиватели событий DOM или подключения к серверу.
Этот хук не вызывается во время рендеринга на стороне сервера
Пример
# onBeforeMount()
- Тип: function onBeforeMount(callback: () => void): void
- Регистрирует перехватчик, который будет вызываться непосредственно перед установкой компонента
- Когда вызывается этот хук, компонент завершил настройку своего реактивного состояния, но узлы DOM еще не созданы. Он собирается впервые выполнить эффект рендеринга DOM.
- Этот хук не вызывается во время рендеринга на стороне сервера
# onBeforeUpdate()
- Тип: function onBeforeUpdate(callback: () => void): void
- Регистрирует перехватчик, который будет вызываться непосредственно перед тем, как компонент собирается обновить свое дерево DOM из-за реактивного изменения состояния.
- Этот хук можно использовать для доступа к состоянию DOM до того, как Vue обновит DOM. Также безопасно изменять состояние компонента внутри этого хука.
- Этот хук не вызывается во время рендеринга на стороне сервера
# onBeforeUnmount()
- Тип: function onBeforeUnmount(callback: () => void): void
- Регистрирует перехватчик, который будет вызываться непосредственно перед отмонтированием экземпляра компонента.
- Когда этот хук вызывается, экземпляр компонента по-прежнему полностью функционален.
- Этот хук не вызывается во время рендеринга на стороне сервера
# onErrorCaptured()
- Регистрирует перехватчик, который будет вызываться при обнаружении ошибки, распространяющейся от компонента-потомка.
Тип:
Ошибки могут быть получены из следующих источников:
- Рендеринг компонентов
- Обработчики событий
- Перехватчики жизненного цикла
- setup() функция
- Наблюдатели
- Пользовательские перехватчики директив
- Переходные крючки
Перехватчик получает три аргумента: ошибку, экземпляр компонента, вызвавшего ошибку, и информационную строку, определяющую тип источника ошибки.
Вы можете изменить состояние компонента в errorCaptured(), чтобы отображать пользователю состояние ошибки. Однако важно, чтобы состояние ошибки не отображало исходное содержимое, вызвавшее ошибку; в противном случае компонент будет помещен в бесконечный цикл рендеринга.
Хук может вернуть false, чтобы остановить дальнейшее распространение ошибки. Подробности о распространении ошибок см. ниже.
Правила распространения ошибок
- По умолчанию все ошибки по-прежнему отправляются на уровень приложения app.config.errorHandler, если он определен, так что об этих ошибках можно по-прежнему сообщать в службу аналитики в одном месте
- Если в цепочке наследования или родительской цепочке компонента существует несколько перехватчиков errorCaptured, все они будут вызваны при одной и той же ошибке в порядке снизу вверх. Это похоже на механизм всплытия собственных событий DOM.
- Если перехватчик errorCaptured сам по себе выдает ошибку, и эта ошибка, и исходная захваченная ошибка отправляются на app.config.errorHandler
- Хук errorCaptured может вернуть false, чтобы предотвратить дальнейшее распространение ошибки. По сути, это означает, что «эта ошибка была обработана и ее следует игнорировать». Это предотвратит вызов дополнительных перехватчиков errorCaptured или app.config.errorHandler для этой ошибки.
# onRenderTracked() DEV ONLY
- Регистрирует перехватчик отладки, который будет вызываться, когда эффект рендеринга компонента отслеживает реактивную зависимость.
- Этот хук доступен только в режиме разработки и не вызывается во время рендеринга на стороне сервера
Тип:
# onRenderTriggered() DEV ONLY
- Регистрирует перехватчик отладки, который будет вызываться, когда реактивная зависимость запускает повторный запуск эффекта рендеринга компонента.
- Этот хук доступен только в режиме разработки и не вызывается во время рендеринга на стороне сервера
Тип:
# onActivated()
- Тип: function onActivated(callback: () => void): void
- Регистрирует обратный вызов, который будет вызываться после вставки экземпляра компонента в DOM как часть дерева, кэшированного KeepAlive
- Этот хук не вызывается во время рендеринга на стороне сервера
# onDeactivated()
- Тип: function onDeactivated(callback: () => void): void
- Регистрирует обратный вызов, который будет вызываться после удаления экземпляра компонента из DOM как части дерева, кэшированного KeepAlive
- Этот хук не вызывается во время рендеринга на стороне сервера
# onServerPrefetch() SSR ONLY
- Тип: function onServerPrefetch(callback: () => Promise
): void - Регистрирует асинхронную функцию, которая должна быть разрешена перед отрисовкой экземпляра компонента на сервере.
- Если обратный вызов возвращает обещание, серверный рендеринг будет ждать, пока обещание не будет разрешено, прежде чем визуализировать компонент.
- Этот хук вызывается только во время рендеринга на стороне сервера и может использоваться для выборки данных только на сервере.
Пример: