# Экземпляры приложения & компонента

# Создание экземпляра приложения

Каждое приложение Vue начинается с создания нового экземпляра приложения с помощью функции createApp:

const app = Vue.createApp({
  /* опции */
})
1
2
3

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

const app = Vue.createApp({})
app.component('SearchInput', SearchInputComponent)
app.directive('focus', FocusDirective)
app.use(LocalePlugin)
1
2
3
4

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

Vue.createApp({})
  .component('SearchInput', SearchInputComponent)
  .directive('focus', FocusDirective)
  .use(LocalePlugin)
1
2
3
4

Полный перечень API приложения можно посмотреть в разделе Справочник API.

# Корневой компонент

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

Приложение должно быть примонтировано в DOM-элемент. Например, если потребуется примонтировать приложение Vue в <div id="app"></div>, то необходимо передать #app:

const RootComponent = {
  /* опции */
}
const app = Vue.createApp(RootComponent)
const vm = app.mount('#app')
1
2
3
4
5

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

Пусть Vue и не реализует паттерн MVVM (opens new window) в полной мере, архитектура фреймворка во многом вдохновлена им. Поэтому переменную с экземпляром приложения традиционно именуют vm (сокращённо от ViewModel).

Хоть все примеры на этой странице нуждаются лишь в одном компоненте, большинство реальных приложений организованы в дерево вложенных, многократно переиспользуемых компонентов. Например, дерево компонентов приложения todo-списка может быть таким:

Корневой компонент
└─ TodoList
   ├─ TodoItem
   │  ├─ DeleteTodoButton
   │  └─ EditTodoButton
   └─ TodoListFooter
      ├─ ClearTodosButton
      └─ TodoListStatistics
1
2
3
4
5
6
7
8

Каждый компонент будет иметь свой собственный экземпляр компонента vm. У некоторых компонентов, таких как TodoItem, вероятно будет несколько экземпляров, отображаемых в один момент времени. Все экземпляры компонентов в этом приложении будут иметь один и тот же экземпляр приложения.

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

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

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

const app = Vue.createApp({
  data() {
    return { count: 4 }
  }
})

const vm = app.mount('#app')

console.log(vm.count) // => 4
1
2
3
4
5
6
7
8
9

Есть и другие опции компонента, которые добавляют определяемые пользователем свойства в экземпляр компонента, например methods, props, computed, inject и setup. Подробнее с каждой из них разберёмся дальше в руководстве. Все свойства экземпляра компонента, независимо от того как они определены, будут доступны в шаблоне компонента.

Vue также предоставляет доступ к некоторым встроенным свойствам через экземпляр компонента, например $attrs и $emit. У таких свойств всегда будет префикс $ во избежание конфликта имён со свойствами, объявляемые пользователем.

# Хуки жизненного цикла

Каждый экземпляр при создании проходит через последовательность шагов инициализации — например, настраивает наблюдение за данными, выполняет компиляцию шаблона, монтирует экземпляр в DOM, обновляет DOM при изменении данных. Между этими шагами вызываются функции, называемые хуками жизненного цикла, предоставляя пользователям возможность выполнять свой код на определённых этапах.

Например, хук created можно использовать для выполнения кода после создания экземпляра:

Vue.createApp({
  data() {
    return { count: 1 }
  },
  created() {
    // `this` указывает на экземпляр vm
    console.log('счётчик: ' + this.count) // => "счётчик: 1"
  }
})
1
2
3
4
5
6
7
8
9

Также есть и другие хуки, которые будут вызываться на различных этапах жизненного цикла экземпляра, например mounted, updated и unmounted. Все хуки вызываются с контекстом this, указывающим на текущий активный экземпляр, который их вызвал.

Совет

Не используйте стрелочные функции (opens new window) в свойствах экземпляра и в коллбэках, например created: () => console.log(this.a) или vm.$watch('a', newVal => this.myMethod()). Так как стрелочные функции не имеют собственного this, то this в коде будет обрабатываться как любая другая переменная и её поиск будет производиться в областях видимости выше до тех пор пока не будет найдена, часто приводя к таким ошибкам, как Uncaught TypeError: Cannot read property of undefined или Uncaught TypeError: this.myMethod is not a function.

# Диаграмма жизненного цикла

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

Хуки жизненного цикла экземпляра

Deployed on Netlify.
Последнее обновление: 2021-03-03, 21:02:34 UTC