Vue.js предоставляет мощный механизм работы с асинхронными
компонентами через <Suspense>. Этот инструмент
позволяет обрабатывать компоненты, загрузка которых может занимать
неопределённое время, при этом обеспечивая пользователю плавный опыт
взаимодействия с интерфейсом.
Асинхронный компонент в Vue определяется как функция, возвращающая
Promise, который разрешается компонентом. Основной
синтаксис:
const AsyncComponent = () => import('./MyComponent.vue');
Загрузка такого компонента может быть отложена или выполняться динамически при необходимости. Асинхронные компоненты полезны для:
<Suspense>Компонент <Suspense> служит контейнером для
асинхронных компонентов. Его задача — управлять состояниями загрузки,
отображая резервный контент до момента, когда асинхронные компоненты
готовы к отображению.
Базовая структура:
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Загрузка...</div>
</template>
</Suspense>
#default: основной контент, который
отобразится после загрузки асинхронного компонента.#fallback: контент, показываемый во
время ожидания.<Suspense> поддерживает одновременное ожидание
нескольких асинхронных компонентов. Фолбэк будет отображаться, пока не
загрузятся все вложенные компоненты.
<Suspense>
<template #default>
<AsyncComponentA />
<AsyncComponentB />
</template>
<template #fallback>
<div>Загрузка компонентов...</div>
</template>
</Suspense>
Vue позволяет добавлять задержку перед показом fallback. Это удобно для предотвращения “мигания” интерфейса при быстрой загрузке компонента.
const AsyncComponent = defineAsyncComponent({
loader: () => import('./MyComponent.vue'),
delay: 200, // миллисекунды
timeout: 3000,
errorComponent: ErrorComponent
});
delay: время, через которое появляется
fallback.timeout: максимальное время ожидания
загрузки компонента.errorComponent: компонент, который
отображается при ошибке загрузки.Асинхронная загрузка может завершиться неудачно, поэтому важно
предусматривать обработку ошибок. defineAsyncComponent
позволяет задать errorComponent и функцию
onError для более тонкого контроля:
const AsyncComponent = defineAsyncComponent({
loader: () => import('./MyComponent.vue'),
onError(error, retry, fail, attempts) {
if (attempts <= 3) {
retry();
} else {
fail();
}
}
});
retry повторяет загрузку
компонента.fail завершает загрузку с
ошибкой.Фолбэк может быть не только статическим, но и динамическим. Например, можно отображать прогресс-бар:
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<ProgressBar :progress="loadingProgress" />
</template>
</Suspense>
Suspense полностью интегрируется с Composition API. Например, при
использовании async setup Vue автоматически воспринимает
setup как асинхронный и может быть обернут в
<Suspense>:
<script setup>
import { ref } from 'vue';
const data = ref(null);
const fetchData = async () => {
const response = await fetch('/api/data');
data.value = await response.json();
};
await fetchData();
</script>
<template>
<Suspense>
<template #default>
<div>{{ data }}</div>
</template>
<template #fallback>
<div>Загрузка данных...</div>
</template>
</Suspense>
</template>
<Suspense> для ленивых страниц и
тяжёлых компонентов.delay, чтобы избежать лишнего мерцания
интерфейса.Suspense не просто отображает спиннер. Он позволяет:
<Suspense> в Vue.js обеспечивает мощный и гибкий
механизм управления асинхронными компонентами, повышает отзывчивость
интерфейса и улучшает пользовательский опыт. С его помощью можно
создавать сложные динамические приложения с плавной загрузкой и надежной
обработкой ошибок.