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

Понимание жизненного цикла компонента Vue js на примере mounted

Автор

Елена Захарова

Введение

Жизненный цикл компонента — это последовательность этапов, через которые проходит каждый компонент Vue.js от создания до удаления со страницы. Хорошее понимание жизненного цикла — одна из базовых вещей для эффективной работы с Vue. Если вы знаете, когда и в каком порядке происходят события, становится намного проще управлять логикой и состоянием ваших компонентов. В этой статье я подробнее расскажу о жизненном цикле на примере одного из самых используемых хуков — mounted. На реальных примерах вы увидите, почему важно знать, как и когда выполнять определённые действия.

Жизненный цикл компонента Vue.js

Общее представление о жизненном цикле

Давайте разберём, что вообще происходит с компонентом Vue, начиная с его появления и вплоть до уничтожения. Вот основные этапы жизненного цикла:

  • Инициализация. Vue создает экземпляр компонента, устанавливает реактивные свойства из data, вычисляемые значения и методы.
  • Монтаж (mounting). Компонент "прикрепляется" к DOM, становится видимым на странице.
  • Обновление. Каждый раз, когда изменяются реактивные данные, компонент реагирует обновлением отображения.
  • Разрушение (unmounting). Компонент удаляется из DOM, и происходит очистка ресурсов.

На каждом из этих этапов срабатывают специальные хуки — "жизненные события". Это функции, которые вы можете определить внутри компонента, чтобы выполнять нужную логику.

Какие жизненные хуки существуют

Основные жизненные хуки в компонентах Vue:

  • beforeCreate — вызывается перед инициализацией данных и событий.
  • created — вызывается непосредственно после инициализации данных.
  • beforeMount — перед тем, как компонент будет смонтирован.
  • mounted — сразу после монтирования в DOM (тема нашей статьи).
  • beforeUpdate — перед тем, как компонент будет обновлён.
  • updated — после обновления DOM из-за реактивных изменений.
  • beforeUnmount (Vue 3) или beforeDestroy (Vue 2) — перед удалением компонента.
  • unmounted (Vue 3) или destroyed (Vue 2) — после удаления элемента и очистки.

Этот набор хуков покрывает все основные события жизненного цикла. Каждый из них решает свои задачи, а сейчас давайте подробнее остановимся на mounted.

Хук mounted: зачем он нужен и когда срабатывает

В чем суть mounted

mounted — это хук жизненного цикла, который вызывается после того, как Vue отрисовал компонент и вставил его в DOM-дерево. Это очень важный момент: если в created элемент в DOM ещё не появился, то в mounted уже можно быть уверенным, что он на странице. Поэтому все действия, которые требуют доступа к реальному DOM (например, работа с библиотеками, которые манипулируют DOM напрямую, или измерение размеров элементов), выполняются именно в этом хуке.

Когда нужно использовать mounted

Здесь некоторые типичные задачи для mounted:

  • Инициализация сторонних библиотек, зависящих от DOM.
  • Получение размеров или положения элементов.
  • Установка обработчиков событий на элементы, которых нет в шаблоне Vue.
  • Первый запуск асинхронных операций, если они зависят от DOM.

Обратите внимание: хотя вы часто будете запускать асинхронный код (например, загрузку данных) в mounted, это не всегда необходимо делать именно здесь. Иногда лучше загружать данные ещё раньше — например, в хуке created.

Простой пример использования mounted

Вот как можно определить и использовать хук mounted в компоненте:

export default {
  name: 'ExampleComponent',
  mounted() {
    // Здесь можно получить доступ к элементам через this.$refs или напрямую к DOM
    console.log('Компонент смонтирован и появился в DOM');
    // Например, измерить элемент по ref
    const height = this.$refs.myBlock.offsetHeight;
    console.log('Высота элемента:', height);
  },
  template: `
    <div ref="myBlock">
      Я пример блока для измерения
    </div>
  `
}

В этом примере мы выводим в консоль сообщение, а также измеряем высоту DOM-элемента после монтирования. Вам не нужно переживать — в этот момент элемент точно уже существует в DOM.

Взаимодействие с DOM и сторонними библиотеками

Частая задача — интеграция библиотек типа jQuery, Chart.js, Leaflet. Если такие библиотеки работают с DOM напрямую, их нельзя запускать до хука mounted: элемент просто не будет найден.

Смотрите, как это реализуется на практике:

import Chart from 'chart.js/auto';

export default {
  mounted() {
    // Здесь this.$refs.chartCanvas гарантированно есть в DOM
    this.chart = new Chart(this.$refs.chartCanvas, {
      type: 'bar',
      data: {...},
      options: {...}
    });
  },
  beforeUnmount() {
    // Важно чистить за собой ресурсы!
    if (this.chart) {
      this.chart.destroy();
    }
  },
  template: '<canvas ref="chartCanvas"></canvas>'
}

В этом коде мы создаем график, после того как элемент canvas появился на странице. И дополнительно проводим очистку в хуке beforeUnmount, чтобы не было утечек памяти.

Асинхронные операции в mounted

Асинхронные задачи вроде загрузки данных часто встречаются в этом хуке. Например, получение данных с сервера:

export default {
  data() {
    return {
      users: []
    }
  },
  async mounted() {
    // Здесь мы можем обращаться к fetch или axios
    const response = await fetch('https://jsonplaceholder.typicode.com/users');
    this.users = await response.json();
  },
  template: `
    <ul>
      <li v-for="user in users" :key="user.id">{{ user.name }}</li>
    </ul>
  `
}

Такой подход удобен, когда вам нужно показать какие-то данные сразу после появления компонента.

Однако, если компоненту не нужен DOM для загрузки данных, такое же действие можно сделать в хуке created — он сработает раньше, что может быть полезно для плавности UI.

Почему не стоит манипулировать DOM до mounted

Обратите внимание: если попытаться обратиться к DOM в хуках вроде created или даже beforeMount, там ещё просто не будет нужных элементов. Покажу вам простую демонстрацию:

export default {
  created() {
    // На этом этапе элементы ещё не существуют, вернется undefined
    console.log(this.$refs.someElement); // undefined
  },
  mounted() {
    // Здесь уже есть доступ к элементу
    console.log(this.$refs.someElement); // DOM-элемент
  },
  template: '<div ref="someElement"></div>'
}

Именно поэтому такие действия возможны только после появления компонента на странице.

Последовательность хуков жизненного цикла (демонстрация)

Чтобы наглядно понять порядок срабатывания хуков, посмотрите, как они выведутся в консоль:

export default {
  beforeCreate() {
    console.log('beforeCreate');
  },
  created() {
    console.log('created');
  },
  beforeMount() {
    console.log('beforeMount');
  },
  mounted() {
    console.log('mounted');
  },
  beforeUpdate() {
    console.log('beforeUpdate');
  },
  updated() {
    console.log('updated');
  },
  beforeUnmount() {
    console.log('beforeUnmount');
  },
  unmounted() {
    console.log('unmounted');
  },
  template: `
    <div>Пример компонента</div>
  `
}

Если вы используете Vue 2, вместо beforeUnmount и unmounted будут beforeDestroy и destroyed. Но логика работы одинаковая.

Как обращаться к элементам через $refs

Основной способ работать с DOM-элементами — это ссылка через ref. Покажу стандартный прием:

export default {
  mounted() {
    // После монтирования $refs.input доступен
    this.$refs.input.focus(); // Установим фокус в поле ввода
  },
  template: '<input ref="input" />'
}

Это полезно для сценариев вроде автозаполнения или инициализации фокуса.

Можно ли передавать параметры в mounted?

Нет, в отличие от обычных методов, жизненные хуки всегда вызываются Vue без параметров. Если вам нужно получить какие-то данные, делайте это через свойства компонента (props), data, или вычисляемые свойства (computed).

Когда mounted НЕ вызывается

Бывают случаи, когда вы ожидаете срабатывания mounted, но хук не вызывается:

  • Если компонент не был добавлен в шаблон или динамически не был смонтирован.
  • Если компонент отрисован с условием (v-if="false"), пока условие не стало истинным.
  • Если компонент был удалён до момента завершения монтирования.

Проверьте, что компонент реально появляется в DOM, иначе чудес не произойдёт.

Использование mounted во Vue 3 и Vue 2

Синтаксис практически не отличается. Главное отличие связано с переходом к Composition API, но сам хук работает одинаково.

Вот пример с Composition API (Vue 3):

import { onMounted, ref } from 'vue';

export default {
  setup() {
    const input = ref(null);

    onMounted(() => {
      // input.value — это DOM-элемент
      input.value.focus();
    });

    return { input };
  },
  template: '<input ref="input" />'
}

onMounted — это аналог стандартного хука, но работает внутри функции setup.

Как правильно управлять ресурсами: очистка и отписка в паре с mounted

Важно помнить: если вы что-то "инициализировали" в mounted, часто требуется делать обратную операцию в хуке "разрушения" (beforeUnmount или destroyed). Это избавит от утечек памяти.

Пример очистки после медиа-запроса:

export default {
  mounted() {
    // Подключаем обработчик события на window
    window.addEventListener('resize', this.handleResize);
  },
  beforeUnmount() {
    // Снимаем обработчик перед удалением компонента
    window.removeEventListener('resize', this.handleResize);
  },
  methods: {
    handleResize() {
      console.log('Изменён размер окна');
    }
  },
  template: '<div>Следим за размером окна</div>'
}

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

Заключение

Хук mounted — один из самых востребованных жизненных хуков в компонентах Vue.js. Он позволяет быть уверенным, что DOM уже существует и можно спокойно выполнять любые действия, связанные с визуализацией, интеграцией внешних библиотек, обработкой событий и измерением элементов страницы. Работа с этим хуком, а также с парными хуками удаления компонентов, лежит в основе грамотного управления жизненным циклом. Регулярное использование mounted делает вашу архитектуру надёжнее, безопаснее и даже улучшает производительность, если вы всё делаете по уму.


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

Как заставить компонент "дождаться" mounted для выполнения асинхронного запроса?

Вам не нужно "ждать" mounted вручную — просто поместите асинхронный запрос внутрь mounted:

mounted() {
  this.loadDataAsync();
},
methods: {
  async loadDataAsync() {
    // ваш запрос тут
  }
}

Vue вызовет mounted тогда, когда компонент будет смонтирован.

Почему $refs иногда равен undefined в mounted?

Если вы используете условный рендеринг (v-if), элемент может появиться в DOM не сразу. Проверьте, что переменная, от которой зависит v-if, истинна к моменту выполнения mounted, или используйте nextTick:

mounted() {
  this.$nextTick(() => {
    // здесь $refs будет точно определён
    console.log(this.$refs.input);
  });
}

Можно ли использовать setTimeout в mounted для задержек?

Да, можно. Основное — очищайте таймеры в хуке beforeUnmount:

mounted() {
  this.timerId = setTimeout(() => { ... }, 1000);
},
beforeUnmount() {
  clearTimeout(this.timerId);
}

Как отследить, что дочерний компонент тоже смонтирован?

Добавьте $refs на дочерний компонент и используйте его $el в $nextTick, или ловите кастомные события, которые эмитятся дочерним компонентом из его mounted:

// В дочернем компоненте
mounted() {
  this.$emit('mounted');
}

Можно ли перезапустить mounted повторно без перерендера всего компонента?

Нет. Хук mounted стандартно вызывается только один раз при монтировании. Если вам нужно повторить некую логику, вынесите её в отдельный метод и вызывайте вручную.


Стрелочка влевоОсновы работы с объектами в VueИспользование метода map в Vue для обработки массивовСтрелочка вправо

Все гайды по Vue

Работа с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueОбзор популярных шаблонов и стартовых проектов на VueКак организовать страницы и маршруты в проекте на VueСоздание серверных приложений на Vue с помощью Nuxt jsРабота со стилями и CSS в Vue js для красивых интерфейсовНастройка и сборка проектов Vue с использованием современных инструментовСоздание и структурирование Vue.js приложения
Управление переменными и реактивными свойствами во VueИспользование v for и slot в VueТипизация и использование TypeScript в VuejsИспользование шаблонов в Vue js для построения интерфейсовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование метода map в Vue для обработки массивовОбработка пользовательского ввода в Vue.jsОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emitИспользование директив и их особенности на Vue с помощью defineСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в Vue
Открыть базу знаний