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

Работа с lifecycle-хуком onMounted во Vue

Автор

Олег Марков

Введение

Во Vue существует целая система жизненного цикла компонента, каждая стадия которого предоставляет свои возможности для выполнения вашего кода. Одной из ключевых точек этого жизненного цикла является момент, когда компонент уже отрисован на странице, и вы готовы обратиться к DOM, выполнить запросы или инициировать работу сторонних библиотек. Именно здесь на помощь приходит жизненный цикл-хук onMounted.
Сегодня мы вместе разберем что такое onMounted, зачем он нужен, какие задачи решает, как правильно его использовать во Vue 3 и чем он отличается от похожих решений в других версиях Vue. По пути рассмотрим много практических примеров.

Хук onMounted — теория и назначение

Что такое lifecycle-хук onMounted

В экосистеме Vue, onMounted — это специальный хук жизненного цикла, который позволяет выполнять ваш код после того, как экземпляр компонента связан с DOM и полностью отрисован. Это значит, что любые манипуляции с DOM-элементами компонента, настройка событий, интеграция внешних библиотек, обращение к ref и многое другое удобно выполнять именно в этом хукe.

В старой опции API (Vue 2.x) для этого использовался метод mounted. В Composition API (тот, что с функциями реактивности и setup) его эквивалентом является функция onMounted.

Когда вызывается onMounted

  • После того как компонент был полностью смонтирован (отрисован) в DOM
  • Все реактивные значения и computed уже работают
  • Все дочерние компоненты прошли свои стадии монтирования

Обратите внимание: хук onMounted не сработает, пока компонент не появился на странице. Если компонент скрыт условием v-if — хук вызовется только при его показе.

Использование onMounted в Composition API

Базовый пример

Давайте разберем основной синтаксис использования onMounted во Vue 3 с помощью Composition API.

<script setup>
// Импортируем функцию onMounted
import { onMounted, ref } from 'vue'

const message = ref('Привет, Vue 3!')

onMounted(() => {
  // Этот код выполнится после монтирования компонента
  console.log('Компонент успешно смонтирован!')
  message.value = 'Компонент уже на странице!'
})
</script>

<template>
  <div>{{ message }}</div>
</template>

Что здесь происходит?
После монтирования компонент выводит сообщение в консоль и сразу обновляет своё реактивное значение message.
onMounted принимает функцию-колбэк, которая и выполняется после полной отрисовки.

Получение доступа к DOM-элементам через ref

Очень часто onMounted используют, чтобы работать с DOM узлами через ref.
Вот пример:

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

// Объявляем ref для DOM-элемента
const inputEl = ref(null)

onMounted(() => {
  // Теперь можно фокусировать input, потому что он гарантированно уже есть в DOM
  inputEl.value.focus()
})
</script>

<template>
  <input ref="inputEl" type="text" placeholder="Курсор появится сразу здесь" />
</template>

Смотрите: только после срабатывания onMounted свойство inputEl.value содержит DOM-элемент, а не null. Вы можете свободно его использовать.

Загрузка данных с сервера

Один из частых кейсов — подгрузка данных с сервера, когда компонент загружается. Обычно работу с API тоже размещают в onMounted.

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

const users = ref([])
const loading = ref(false)
const error = ref(null)

onMounted(async () => {
  loading.value = true
  try {
    const response = await fetch('https://jsonplaceholder.typicode.com/users')
    users.value = await response.json()
  } catch (e) {
    error.value = 'Ошибка загрузки данных'
  } finally {
    loading.value = false
  }
})
</script>

<template>
  <div v-if="loading">Загрузка...</div>
  <div v-else-if="error">{{ error }}</div>
  <ul v-else>
    <li v-for="user in users" :key="user.id">
      {{ user.name }}
    </li>
  </ul>
</template>

Обратите внимание, что здесь используется асинхронная функция внутри onMounted. Это разрешено и довольно удобно.

Интеграция сторонних библиотек

Давайте рассмотрим ситуацию, когда вам необходимо подключить плагин или библиотеку, работающую с DOM. Например, инициализировать datepicker или библиотеку визуализации данных.

<script setup>
import { ref, onMounted } from 'vue'
import Pikaday from 'pikaday'

const pickerEl = ref(null)

onMounted(() => {
  // Инициализация Pikaday после появления элемента в DOM
  new Pikaday({
    field: pickerEl.value
  })
})
</script>

<template>
  <input ref="pickerEl" placeholder="Выберите дату" />
</template>

Важно! Все сторонние библиотеки, связанные с реальным DOM, должны инициализироваться именно в onMounted.

Несколько onMounted в одном компоненте

Во Vue 3 вы спокойно можете вызывать onMounted несколько раз в одном компоненте, например:

<script setup>
import { onMounted } from 'vue'

onMounted(() => {
  console.log('Первое действие при монтировании')
})

onMounted(() => {
  console.log('Второе действие при монтировании')
})
</script>

Все функции будут вызваны по очереди.

Совместное использование onMounted и других хуков (onUpdated, onUnmounted)

Иногда возникает ситуация: вы инициализируете стороннюю библиотеку в onMounted и хотите корректно её удалить при размонтировании компонента.
Для этого используйте пару onMounted и onUnmounted:

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

const intervalId = ref(0)

onMounted(() => {
  // Запускаем таймер при монтировании
  intervalId.value = setInterval(() => {
    console.log('Таймер тикает')
  }, 1000)
})

onUnmounted(() => {
  // Очищаем таймер при размонтировании
  clearInterval(intervalId.value)
})
</script>

Такой подход предотвращает утечки памяти и ошибки при повторном монтировании компонента.

onMounted: Различия во Vue 2 и Vue 3

Сравнение Options API (Vue 2) и Composition API (Vue 3)

В классическом Options API (Vue 2) вы использовали вот такой синтаксис: js export default { data() { return { count: 0 } }, mounted() { console.log('Компонент смонтирован') } }

С приходом Composition API (Vue 3) всё выглядит чуть иначе: ```js import { onMounted } from 'vue'

export default { setup() { onMounted(() => { console.log('Компонент смонтирован в setup') }) } } ```

Главное отличие: в Vue 3 с Composition API хук может использоваться гораздо более гибко — его можно вызывать сколько угодно раз, группировать с другими реактивными функциями, выносить в кастомные хуки (use-функции).

Передача хуков между компонентами

Вот как можно вынести логику монтирования в отдельную функцию и переиспользовать:

// useLogger.js
import { onMounted } from 'vue'

export function useLogger(msg) {
  onMounted(() => {
    console.log(msg)
  })
}

// MyComponent.vue
<script setup>
import { useLogger } from './useLogger'

useLogger('Компонент загружен!')
</script>

Это одно из ключевых преимуществ Composition API.

onMounted в сложных компонентах

Когда монтируются родительские и дочерние компоненты

Может возникнуть вопрос: что если у компонента есть дочерние компоненты, чей onMounted срабатывает первым?
Во Vue хук onMounted вызывается для дочерних компонентов раньше, чем для родителя.
Смотрите порядок на примере:

// Parent.vue
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
  console.log('Родитель смонтирован')
})
</script>
<template>
  <Child />
</template>

// Child.vue
<script setup>
import { onMounted } from 'vue'
onMounted(() => {
  console.log('Дочерний компонент смонтирован')
})
</script>

В консоли вы увидите: Дочерний компонент смонтирован Родитель смонтирован

Это позволяет гарантировать, что когда родитель "очнулся", дочерние уже на месте и доступны для взаимодействия.

onMounted и v-if/v-for

onMounted не срабатывает, пока компонент не был реально добавлен в DOM.
Если элемент спрятан через v-if или добавляется через v-for — хук вызовется только когда соответствующее условие выполнится.

<Child v-if="showChild" />

Если showChild false — Child не монтируется и onMounted НЕ срабатывает.

Динамическая загрузка компонентов

Если используете dynamic imports или динамически управляете списком компонентов (например, tabs), то onMounted вызовется при первом появлении компонента на странице, а при повторном использовании сам по себе не вызывает этот хук снова (если компонент не был уничтожен).

Особенности использования onMounted

Можно ли использовать асинхронные функции внутри onMounted

Да, внутри onMounted можно использовать async-функции, однако сам onMounted не ждет завершения асинхронной операции:

onMounted(async () => {
  await fetchData()
})

Vue не ждет, когда fetchData завершится — основной поток инициализации компонентов продолжается.

Не используйте onMounted вне setup

onMounted работает только внутри setup (или внутри composable-функций, вызываемых из setup). Снаружи setup onMounted работать не будет.

Доступ к this внутри onMounted

В Composition API вы НЕ работаете с this — используйте объявленные в scope переменные и ref.

Краткая памятка по onMounted

Когда использовать:

  • Нужно инициализировать данные только при первом появлении компонента
  • Требуется настроить сторонний плагин, работу со сторонним DOM-API
  • Необходимо взаимодействие с ref-элементами
  • Нужно выполнить асинхронную загрузку данных после отрисовки

Когда не использовать:

  • Когда задача не связана с DOM, загрузкой данных или инициализацией сервисов под конкретный компонент при его появлении
  • Для вычислений, которые могут быть выполнены до отрисовки

Заключение

onMounted — один из основных "точек входа" в жизненном цикле компонента во Vue. Это универсальный инструмент для работы с DOM, запуска загрузки данных и установки вспомогательных библиотек строго в момент появления компонента на странице. Используя его грамотно, вы сделаете свои компоненты предсказуемыми, надежными и чистыми, уменьшите вероятность ошибок, связанных с несвоевременным доступом к DOM или зависимостями.
Теперь у вас под рукой богатый арсенал практических примеров и вы владеете тонкостями применения onMounted в рамках современного Composition API.

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

Как правильно сбросить или "очистить" действия, начатые в onMounted, чтобы избежать утечек памяти?

Часто нужно завершить обработчики событий, очищать интервалы или уничтожать плагины. Для этого используйте связку onMounted и onUnmounted:

let intervalId

onMounted(() => {
  intervalId = setInterval(() => { /* ... */ }, 1000)
})

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

Как протестировать onMounted в unit-тестах?

Воспользуйтесь @vue/test-utils и методами mount, shallowMount. После монтирования компонента onMounted запустится автоматически. Можно проверять side-effect'ы или мокать асинхронные вызовы.

const wrapper = mount(MyComponent)
// onMounted выполнится, проверяйте эффекты напрямую

Почему onMounted не срабатывает при условном рендеринге компонента (v-if)?

onMounted вызовется только при фактическом появлении компонента в DOM. Если v-if изначально false, компонент не инициализируется. Переведите v-if в true, и хук сразу же сработает.

Нужно ли использовать watch внутри onMounted, если требуется отследить изменение props?

Нет, onMounted активируется только один раз, при первом появлении компонента. Для отслеживания изменений используйте watch или watchEffect.

Можно ли использовать onMounted внутри кастомного composable-файла (use-логики)?

Да, это распространённый паттерн. Просто вызовите onMounted внутри вашей функции, а функцию — внутри setup. Vue сам организует правильное выполнение хуков в нужном контексте.


Стрелочка влевоУправление параметрами и динамическими данными во VueОсновы работы с объектами в VueСтрелочка вправо

Все гайды по Vue

Руководство по валидации форм во Vue.jsИнтеграция Tiptap для создания редакторов на VueРабота с таблицами во Vue через TanStackИнструкция по установке и компонентам Vue sliderУправление пакетами Vue js с помощью npmУправление пакетами и node modules в Vue проектахКак использовать meta для улучшения SEO на VueПолный гайд по компоненту messages во Vuejs5 правил использования Inertia с Vue и LaravelРабота с модулями и пакетами в VueИнструкция по работе с grid на 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Использование query-параметров и их обработка в маршрутах VueЗагрузка и управление состоянием загрузки в 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
5 библиотек для создания tree view во VueИнтеграция Tailwind CSS с 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 для взаимодействия компонентовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsРабота со свойствами компонентов VueУправление параметрами и динамическими данными во VueРабота с lifecycle-хуком onMounted во VueОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование модальных окон modal в Vue приложенияхИспользование методов в компонентах Vue для обработки логикиИспользование метода map в Vue для обработки массивовИспользование хуков жизненного цикла Vue для управления состоянием компонентаОбработка пользовательского ввода в Vue.jsРабота с изображениями и их оптимизация в VueРабота с ключами key в списках и компонентах 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 ChartСоздание и настройка кнопок в VueСоздание и настройка кнопок в 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
Открыть базу знаний