Вопрос или проблема
Я пишу приложение на Vue 3 и использую suspense. Оно не работает так, как я ожидал, поэтому я нашел кодпен, который делает то, что мне нужно: https://codepen.io/ajithranka/pen/RwjBJbr
Я экспортировал его и запустил локально без проблем. Затем я создал стандартное приложение Vue:
npm create vite@latest loading-app -- --template vue
Затем я создал компоненты и виды Vue, и когда я запускаю новое приложение, я получаю:
Я знаю, что значит ошибка, но не понимаю, почему это происходит. Даже когда я проверяю, что переменная данных не равна null, скелеты не появляются.
Я создал публичный проект на github (https://github.com/troycomp/loading-app) с тем, что я создал из кодпена. Может кто-то показать мне, почему скелеты не появляются, как в примере?
Спасибо
Согласно документации Vue:
Существует два типа асинхронных зависимостей, на которые может ждать
<Suspense>
:
Компоненты с асинхронным хуком setup(). Это включает компоненты, использующие
<script setup>
с выражениями await верхнего уровня.Асинхронные компоненты.
В вашем коде на github, в SuspendableComponent.vue, вы выполняете запрос в хуке onMounted
onMounted(async () => {
data.value = await fetchData({
dataIndex: props.dataIndex,
delay: props.delay,
throwError: props.throwError,
});
});
Это не считается кодом верхнего уровня, поэтому <Suspense>
не ждет его. Чтобы быть кодом верхнего уровня, получение данных должно быть перемещено за пределы onMounted.
data.value = await fetchData({
dataIndex: props.dataIndex,
delay: props.delay,
throwError: props.throwError,
});
Ответ или решение
Проблема с использованием Vue 3 Suspense и загрузочных скелетов
Введение
При разработке приложения на Vue 3 с использованием функциональности Suspense
вы можете столкнуться с проблемами отображения загрузочных скелетов. В данной статье мы рассмотрим основные причины, по которым ваши загрузочные скелеты могут не отображаться, и предложим решения для их исправления.
Описание проблемы
Вы описали свою ситуацию, в которой при использовании Suspense
в вашем приложении загрузочные скелеты не отображаются так, как вы ожидали. Этот вопрос был выявлен в процессе работы с компонентами и использованием асинхронного кода. Для иллюстрации вашей проблемы вы предоставили ссылку на проект на GitHub и ссылку на код, который работал корректно на CodePen.
Основные аспекты Suspense
в Vue 3
Согласно документации Vue, компонент <Suspense>
может ожидать два типа асинхронных зависимостей:
- Компоненты с асинхронной
setup()
-функцией, включая компоненты, использующие<script setup>
с применениемtop-level await
. - Асинхронные компоненты.
Ключевым моментом здесь является понимание того, как Vue обрабатывает асинхронные операции. Чтобы компонент успешно ожидал выполнения асинхронной логики и отображал загрузочные скелеты, код должен быть написан определенным образом.
Причина проблемы
В вашем коде в компоненте SuspendableComponent.vue
вы выполняете загрузку данных внутри хука onMounted
:
onMounted(async () => {
data.value = await fetchData({
dataIndex: props.dataIndex,
delay: props.delay,
throwError: props.throwError,
});
});
Такой подход не считается "top-level" кодом. Это означает, что Vue не может ожидать завершения этого асинхронного вызова, и, следовательно, не сможет показать загрузочный скелет.
Решение
Чтобы решить эту проблему, вам необходимо вынести асинхронный код за пределы onMounted
и использовать async
на самом верхнем уровне вашего компонента. Ниже представлен пример, как вы можете это сделать:
const data = ref(null);
const fetchDataAsync = async () => {
data.value = await fetchData({
dataIndex: props.dataIndex,
delay: props.delay,
throwError: props.throwError,
});
};
// Вызов асинхронной функции
fetchDataAsync();
Этот подход позволяет Vue правильно ждать завершения загрузки данных и корректно отображать скелеты.
Заключение
Решение проблемы с отображением загрузочных скелетов в Vue 3 Suspense
заключается в том, чтобы убедиться, что асинхронные операции выполнены на верхнем уровне. Это позволит Suspense
корректно управлять состоянием загрузки и обеспечит правильное отображение интерфейса вашего приложения.
Если после внесения предложенных изменений проблема все еще сохраняется, рекомендуется проверить дополнительные аспекты вашего приложения, такие как конфигурация Vite, структура компонентов и обработка ошибок. Успехов в разработке!