0Pricing
Vue Academy · Урок

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

defineAsyncComponent(), loadingComponent, errorComponent, параметры delay и timeout

«Асинхронные компоненты с defineAsyncComponent» — бесплатный урок Vue Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Vue Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Vue Academy содержит 4 уроков всего.

Зачем нужны асинхронные компоненты

defineAsyncComponent позволяет загружать компонент лениво — его код загружается только при первом отображении компонента.

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

Форма с функцией загрузки

В простейшем варианте передаётся функция загрузки, возвращающая динамический import(). Vite и webpack автоматически выделяют этот импорт в отдельный фрагмент.

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

const SettingsModal = defineAsyncComponent(() =>
  import('./SettingsModal.vue')
)
</script>

<template>
  <SettingsModal v-if="showSettings" />
</template>

Форма с объектом параметров

Для более точного управления передайте объект параметров. Основные поля:

  • загрузчик — функция динамического импорта
  • loadingComponent — отображается во время загрузки
  • errorComponent — отображается при неудачной загрузке
  • задержка / время ожидания — параметры управления временем
import { defineAsyncComponent } from 'vue'
import Loading from './Loading.vue'
import ErrorView from './ErrorView.vue'

const AsyncChart = defineAsyncComponent({
  loader: () => import('./Chart.vue'),
  loadingComponent: Loading,
  errorComponent: ErrorView,
  delay: 200,
  timeout: 5000
})

Задержка: как избежать краткого появления индикатора

Параметр delay (по умолчанию 200 мс) определяет, сколько Vue ждёт перед показом loadingComponent. Если фрагмент загружается быстрее заданной задержки, индикатор загрузки вообще не появляется.

Установите delay: 0, чтобы сразу показывать состояние загрузки.

const AsyncPanel = defineAsyncComponent({
  loader: () => import('./Panel.vue'),
  loadingComponent: Spinner,
  // wait 300ms before showing Spinner
  delay: 300
})

Максимальное время ожидания: обработка медленной загрузки

Параметр timeout задаёт максимальное время ожидания. Если загрузчик не завершится в течение timeout мс, будет показан errorComponent, а ошибка будет записана в журнал.

По умолчанию ограничение по времени отсутствует — загрузка продолжается бесконечно.

const AsyncReport = defineAsyncComponent({
  loader: () => import('./Report.vue'),
  errorComponent: ErrorView,
  // fail if not loaded within 10s
  timeout: 10000
})

Обратный вызов onError

Обработчик onError запускается, когда загрузчик отклоняет запрос. Он получает ошибку, функцию повтора, функцию отказа и текущее число попыток.

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

const AsyncWidget = defineAsyncComponent({
  loader: () => import('./Widget.vue'),
  onError(error, retry, fail, attempts) {
    if (attempts <= 3) {
      retry()   // try loading again
    } else {
      fail()    // give up, show errorComponent
    }
  }
})

Решение: повторить попытку или завершить с ошибкой

Внутри onError необходимо вызвать ровно одну из функций — retry() или fail() (или ни одну, что также приводит к ошибке). Распространённая стратегия: несколько раз повторять попытку при сетевых ошибках, но сразу завершать работу при ошибке синтаксиса или загрузки фрагмента, которую повторная попытка не исправит.

onError(error, retry, fail, attempts) {
  const isNetwork = /Loading chunk/.test(error.message)
  if (isNetwork && attempts <= 2) {
    retry()
  } else {
    fail()
  }
}

Использование вместе с Suspense

Когда асинхронный компонент находится внутри границы Suspense, состоянием загрузки управляет сама граница. В этом случае собственный loadingComponent компонента игнорируется — используется резервный вариант Suspense.

<template>
  <Suspense>
    <AsyncChart />  <!-- loadingComponent ignored here -->
    <template #fallback>Loading chart...</template>
  </Suspense>
</template>

Именованные фрагменты для отладки

Сгенерированному фрагменту можно задать имя с помощью специального комментария. Благодаря этому сетевые запросы и отчёты о пакетах становятся понятнее.

const AsyncEditor = defineAsyncComponent(() =>
  import(
    /* webpackChunkName: "editor" */
    './RichTextEditor.vue'
  )
)

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

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

<template>
  <AsyncProfile
    :user-id="id"
    @save="handleSave"
  />
</template>

<!-- AsyncProfile resolves to the real component, props/events pass through -->

Рекомендация: осторожно откладывайте загрузку видимых при прокрутке компонентов

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

// Good candidate: modal only opened on click
const Modal = defineAsyncComponent(() => import('./Modal.vue'))

// Poor candidate: hero shown immediately on load
// import Hero directly instead

Быстрая проверка

Проверьте своё понимание defineAsyncComponent.

Повторение

Вы узнали об асинхронной загрузке компонентов с помощью defineAsyncComponent:

  • Форма с загрузчиком возвращает динамический import() для разделения кода
  • Форма с параметрами добавляет loadingComponent, errorComponent, delay, timeout
  • delay предотвращает краткое появление индикатора загрузки, а timeout завершает медленные загрузки с ошибкой
  • onError(error, retry, fail, attempts) реализует логику повторной попытки или отказа
  • Внутри Suspense резервный вариант границы управляет интерфейсом загрузки

Часто задаваемые вопросы

Урок «Асинхронные компоненты с defineAsyncComponent» бесплатный?

Да — полный текст урока «Асинхронные компоненты с defineAsyncComponent» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Vue Academy, подпишись на CoddyKit PRO. Курс Vue Academy содержит 4 уроков всего.

Чему я научусь в уроке «Асинхронные компоненты с defineAsyncComponent»?

defineAsyncComponent(), loadingComponent, errorComponent, параметры delay и timeout Ты практикуешь Vue Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Vue Academy?

Предыдущий опыт не требуется. Vue Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.

Сколько времени занимает урок «Асинхронные компоненты с defineAsyncComponent»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Vue Academy?

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

Все уроки этого курса

  1. Компонент Vue Suspense
  2. Асинхронные компоненты с defineAsyncComponent
  3. Потоковый SSR с renderToWebStream
  4. Стратегии отложенной гидратации
← Назад к Vue Academy