vue2_rus

Динамические и асинхронные компоненты

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

keep-alive с динамическими компонентами

Ранее мы использовали атрибут is для переключения компонентов во вкладках:

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

Вы можете заметить, что если выбрать запись, переключиться на вкладку Archive, затем переключиться обратно на Posts, то больше не будет показываться выбранная запись. Это связано с тем, что каждый раз, когда вы переключаетесь на новую вкладку, Vue создаёт новый экземпляр currentTabComponent.

Пересоздание динамических компонентов обычно является полезным поведением, но в нашем случае, мы хотим чтобы экземпляры компонентов вкладок кэшировались после их создания в первый раз. Для решения этой проблемы мы можем обернуть наш динамический компонент в элемент <keep-alive>:

<!-- Неактивные компоненты будут закэшированы! -->
<keep-alive>
  <component v-bind:is="currentTabComponent"></component>
</keep-alive>

Теперь вкладка Posts управляет собственным состоянием (выбранной записью) даже когда не отображается. Обратите внимание, что <keep-alive> требует, чтобы у всех переключаемых компонентов было задано имя, либо через настройку name компонента, либо через местную/глобальную регистрацию.

Подробнее с элементом <keep-alive> можно ознакомиться на странице API.

Асинхронные компоненты

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

Vue.component('async-example', function (resolve, reject) {
  setTimeout(function () {
    // Передаём определение компонента в обратновызов resolve
    resolve({
      template: '<div>Я — асинхронный!</div>'
    })
  }, 1000)
})

Функция-фабрика принимает параметр resolve — обратновызов, который вызывается после того, как определение компонента получено от сервера. Кроме того, можно вызвать reject(reason), если загрузка по какой-либо причине не удалась. Мы используем setTimeout исключительно в демонстрационных целях; как именно получать компонент в рабочей ситуации — решать только вам самим.

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

new Vue({
  // ...
  components: {
    'my-component': () => import('./my-async-component')
  }
})

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

Добавлено в версии 2.3.0+

Фабрика асинхронного компонента также может возвращать объект следующего формата:

const AsyncComponent = () => ({
  // Загружаемый компонент. Значение должно быть Promise
  component: import('./MyComponent.vue'),
  // Компонент загрузки, используемый пока загружается асинхронный компонент
  loading: LoadingComponent,
  // Компонент ошибки, используемый при неудачной загрузке
  error: ErrorComponent,
  // Задержка перед показом компонента загрузки. По умолчанию: 200 мс.
  delay: 200,
  // Компонент ошибки будет отображаться, если отсрочка
  // была указана и время ожидания превышено. По умолчанию: Infinity.
  timeout: 3000
})

Обратите внимание, что вы должны использовать Vue Router версии 2.4.0+ если вы хотите использовать указанный выше синтаксис для компонентов маршрута.