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

Как работать с экземплярами компонента Instance во Vue

Автор

Олег Марков

Введение

Vue — популярный JavaScript-фреймворк для создания пользовательских интерфейсов. Главный строительный блок любого приложения на Vue — это компоненты. За каждым компонентом стоит его экземпляр (instance), который отвечает за все внутренние процессы: хранение состояния, реактивность, обработку событий и управление жизненным циклом. Ваше понимание того, как работать с экземплярами компонентов, поможет создавать более динамичные, управляемые и производительные приложения.

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

Что такое экземпляр компонента (Instance) во Vue

Экземпляр компонента Vue — это объект, созданный конструктором Vue, который связывает данные, методы, шаблоны, вычисляемые свойства и другое между собой для конкретного компонента. Каждый раз, когда вы используете компонент в шаблоне, для него создается свой отдельный экземпляр со своим состоянием.

Экземпляр компонента управляет:

  • Реактивностью данных
  • Жизненным циклом (mount, updated, destroyed и пр.)
  • Вызовом методов компонентов
  • Доступом к свойствам и дочерним компонентам

Экземпляр создается автоматически, когда вы используете Vue-компонент в шаблоне или вручную, если создаете компонент программно.

Как создаётся экземпляр компонента

Давайте рассмотрим фундаментальный пример, чтобы закрепить теорию:

// Создание корневого экземпляра Vue
const app = Vue.createApp({
  data() {
    return {
      message: 'Привет, Vue!'
    }
  }
})

// Монтируем компонент на элемент #app
const vm = app.mount('#app')

Здесь vm — это экземпляр компонента (instance) для вашего Vue-приложения. Он открывает доступ ко всем публичным свойствам и методам, которые вы определили.

Свойства и методы экземпляра компонента

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

Доступ к данным из экземпляра

С помощью экземпляра вы можете получить доступ к любым данным, определённым в компоненте:

const vm = app.mount('#app')
console.log(vm.message) 
// Выведет: Привет, Vue!

Изменение данных через экземпляр

Данные, объявленные в функции data, можно изменять напрямую через экземпляр:

vm.message = 'Новое сообщение'
// Интерфейс автоматически отобразит обновлённые данные

Вызов методов компонента через экземпляр

Пример компонента с методом:

const app = Vue.createApp({
  data() {
    return {
      count: 0
    }
  },
  methods: {
    increment() {
      this.count += 1
    }
  }
})

const vm = app.mount('#app')
vm.increment()
console.log(vm.count) // 1

Использование вычисляемых свойств (computed) через экземпляр

Вычисляемые свойства, определённые в компоненте, доступны из экземпляра:

const app = Vue.createApp({
  data() {
    return {
      firstName: 'Иван',
      lastName: 'Иванов'
    }
  },
  computed: {
    fullName() {
      return this.firstName + ' ' + this.lastName
    }
  }
})

const vm = app.mount('#app')
console.log(vm.fullName) // Иван Иванов

Работа с классическим и Composition API

В класcическом API (Options API) все методы и свойства экземпляра доступны напрямую через созданный объект. В Composition API большинство логики инкапсулировано внутри setup(), но шаблон по-прежнему работает с скоупом экземпляра.

const app = Vue.createApp({
  setup() {
    const message = Vue.ref('Hello, Composition!')
    function updateMessage() {
      message.value = 'Updated'
    }
    return { message, updateMessage }
  }
})

const vm = app.mount('#app')
console.log(vm.message) // Hello, Composition!
vm.updateMessage()
console.log(vm.message) // Updated

Важно: в Composition API все реактивные переменные — это ref или reactive объекты, их значения доступны через .value, но при доступа через экземпляр vm эти значения обычно уже раскрыты.

Жизненный цикл экземпляра компонента

Каждый экземпляр компонента проходит через серии этапов. Очень важно знать, на каком этапе можно безопасно выполнять определённые действия.

Основные хуки жизненного цикла

  • beforeCreate — компонент только создается, данные ещё не реактивны
  • created — данные уже реактивны, можно обращаться к data и methods
  • beforeMount — компонент еще не смонтирован в DOM
  • mounted — компонент прикреплён к DOM
  • beforeUpdate — данные изменились, но DOM еще не обновился
  • updated — DOM обновлён
  • beforeUnmount — перед удалением из DOM
  • unmounted — компонент удалён из DOM

Давайте рассмотрим, как использовать эти хуки:

const app = Vue.createApp({
  data() {
    return { count: 0 }
  },
  created() {
    // Данные уже реактивны
    console.log('Компонент создан, count:', this.count)
  },
  mounted() {
    // Теперь можно работать с DOM
    console.log('Компонент примонтирован!')
  }
})

В Composition API хуки вызываются как отдельные функции, например: onMounted(() => { ... }).

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

Вы часто захотите обратиться к экземпляру компонента для задания начальных параметров или подписки на события. Вот пример:

created() {
  // Можно использовать this для доступа к данным и методам
  this.initApp()
},
methods: {
  initApp() {
    // Инициализация приложения
  }
}

Динамическое создание экземпляров (Программные компоненты)

В некоторых случаях вам нужно создавать компоненты не в шаблоне, а программно — например, для всплывающих окон, модальных форм или сообщений.

Пример динамического создания экземпляра

// Определяем компонент
const MessageComponent = {
  template: '<div>{{ text }}</div>',
  props: ['text']
}

// Создаём приложение
const app = Vue.createApp(MessageComponent, { text: 'Динамическое сообщение' })

// Монтируем в специфическую DOM-ноду или создаём её программно
const container = document.createElement('div')
document.body.appendChild(container)
const vm = app.mount(container)
// Теперь экземпляр vm с данным сообщением появился в DOM вне основного дерева приложения

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

Доступ к дочерним компонентам и рефам

Работая с экземплярами, часто возникает задача управлять дочерними компонентами, обращаться к их методам или состоянию.

Использование ref для доступа к компоненту

В шаблоне вы задаёте реф:

<MyChildComponent ref="childComp" />

В методах родителя вы можете обратиться к дочернему компоненту:

mounted() {
  // this.$refs содержит все элементы и компоненты с ref
  this.$refs.childComp.doSomething()
}

Помните: доступ к $refs возможен только после монтирования компонента!

Интернал-свойства экземпляра ($props, $el, $emit, $root, $parent и др.)

Vue инстанс предоставляет набор системных свойств, они начинаются с $. Вот наиболее часто используемые из них:

СвойствоНазначение
$elDOM-элемент, в который смонтирован компонент
$refsСсылки на внутренние элементы/компоненты с ref
$parentЭкземпляр родительского компонента
$rootКорневой экземпляр приложения
$emitМетод для генерации событий
$optionsИсходные опции компонента
$propsОбъект всех props, переданных компоненту

Посмотрите, как воспользоваться этими свойствами:

mounted() {
  console.log('DOM-элемент компонента:', this.$el)
  console.log('Свойства компонентов:', this.$props)
  this.$emit('some-event') // Генерируем событие
}

Работа с $parent и $root

Иногда нужно обратиться к данным или методам родителя или корневого экземпляра:

this.$parent.someParentMethod()
this.$root.globalMethod()

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

Применение экземпляра компонента для глобального управления

Можно использовать корневой экземпляр ($root) или создавать специальное глобальное событие-коммуникатор через экземпляр Vue для loosely-coupled взаимодействий.

Пример глобального события

// Создаём глобальный event bus
const eventBus = Vue.createApp({}).mount(document.createElement('div'))

// Где-то в компоненте:
eventBus.$emit('show-message', 'Привет, мир!')

// В другом месте приложения можно подписаться:
eventBus.$on('show-message', (text) => {
  // Делаем что-то при возникновении события
})

В Vue 3 eventBus в таком виде не поддерживается из коробки, для глобального взаимодействия используйте provide/inject, сторонние библиотеки или глобальные состояния.

Интроспекция экземпляра: что можно, а что нельзя делать

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

  • Изменять свойства, начинающиеся с $ или _ (это внутренние API)
  • Модифицировать данные напрямую вне функций жизненного цикла или реактивных методов
  • Полагаться на структуру private свойств, которые могут измениться между версиями Vue

Примеры практических задач

Программное управление состоянием дочернего компонента

// Родительский компонент
methods: {
  resetChildCounter() {
    this.$refs.childComp.resetCounter()
  }
}
<ChildComponent ref="childComp" />
<button @click="resetChildCounter">Сбросить счетчик у дочернего компонента</button>

Асинхронная инициализация данных через created/mounted

created() {
  this.fetchData()
},
methods: {
  async fetchData() {
    this.items = await fetch('/api/items').then(r => r.json())
  }
}

Программное уничтожение экземпляра

В некоторых случаях требуется уничтожить экземпляр вручную:

// Для Vue 2
vm.$destroy()
// Для Vue 3
app.unmount() // Или vm.$el.remove() для удаления DOM-элемента

Заключение

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

Вы познакомились с основными API, способами доступа к данным, методам, рефам, узнали о жизненном цикле компонента, научились создавать и монтировать экземпляры программно, пользоваться системными свойствами-интерфейсами и обращать к дочерним/родительским компонентам. Это база, необходимая для понимания и успешного применения Vue в реальных задачах.


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

Как получить доступ к данным setup() из экземпляра vm в Composition API?

Через экземпляр vm доступны только те свойства и методы, которые возвращены из функции setup(). Если вы определяете переменные через ref или reactive, их значения также доступны через vm, но уже как обычные значения (развёрнутые). Например:

const app = Vue.createApp({
  setup() {
    const count = Vue.ref(0)
    return { count }
  }
})
const vm = app.mount('#app')
console.log(vm.count) // 0, доступ через экземпляр

Почему $refs возвращает undefined при попытке доступа к дочернему компоненту?

$refs заполняется только после монтирования компонента. Если попытаться обратиться к $refs в created или setup, он будет пустым. Применяйте доступ к $refs только в хуке mounted или позже.

mounted() {
  this.$refs.childComp.doSomething()
}

Как правильно уничтожить экземпляр компонента во Vue 3?

В Vue 3 экземпляр компонента уничтожается методом unmount у приложения:

const app = Vue.createApp(Component)
const vm = app.mount('#target')
// Чтобы уничтожить:
app.unmount()

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

Как программно добавить компонент в произвольный элемент DOM?

Создайте новый контейнер-элемент, добавьте его в DOM и смонтируйте компонент через app.mount:

const container = document.createElement('div')
document.body.appendChild(container)
const app = Vue.createApp(MyComponent)
const vm = app.mount(container)

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

Каждый раз при использовании компонента в шаблоне создаётся свой экземпляр с независимым состоянием. Для обращения к определённому экземпляру используйте уникальные ref или передавайте идентификаторы через props. Например:

<MyComponent ref="comp1" />
<MyComponent ref="comp2" />

Можете затем обращаться к this.$refs.comp1 и this.$refs.comp2.

Стрелочка влевоРабота с JSON данными в приложениях VueПолучение данных и API-запросы во Vue.jsСтрелочка вправо

Все гайды по 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 для управления состоянием компонентаРабота с ключами key в списках и компонентах VueОбработка пользовательского ввода в Vue.jsРабота с изображениями и их оптимизация в 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
Открыть базу знаний