JAVASCRIPT
Manage Asynchronous Components and Data Fetching with Vue 3 Suspense
Utilize Vue 3's Suspense component to elegantly handle asynchronous operations, displaying a fallback loading state while waiting for components or data to resolve.
// src/components/AsyncDataComponent.vue
<template>
<div class="async-data">
<h2>Fetched Data</h2>
<p v-if="data">Data from API: {{ data.value }}</p>
<p v-else>No data loaded yet.</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
const data = ref(null);
// Simulate an async data fetch
await new Promise(resolve => setTimeout(resolve, 2000));
data.value = { value: 'Successfully loaded data!' };
</script>
// src/App.vue
<template>
<h1>Vue 3 Suspense Demo</h1>
<Suspense>
<!-- Main content to render once async components/data are resolved -->
<template #default>
<AsyncDataComponent />
</template>
<!-- Content to render while async components/data are loading -->
<template #fallback>
<div class="loading-state">
<p>Loading data... Please wait.</p>
<div class="spinner"></div>
</div>
</template>
</Suspense>
<p>This content is outside Suspense and renders immediately.</p>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
import AsyncDataComponent from './components/AsyncDataComponent.vue';
// A more explicit way to define an async component (optional for script setup)
// const AsyncDataComponent = defineAsyncComponent(() =>
// import('./components/AsyncDataComponent.vue')
// );
</script>
<style>
.loading-state {
padding: 20px;
border: 1px dashed #ccc;
text-align: center;
margin-top: 20px;
}
.spinner {
border: 4px solid rgba(0, 0, 0, 0.1);
border-left-color: #333;
border-radius: 50%;
width: 24px;
height: 24px;
animation: spin 1s linear infinite;
margin: 10px auto;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
.async-data {
background-color: #e6ffe6;
padding: 15px;
border-radius: 5px;
margin-top: 20px;
}
</style>
How it works: This snippet demonstrates Vue 3's `Suspense` component, which allows handling asynchronous operations like data fetching or loading async components. The `App.vue` component uses `<Suspense>` with a `#default` slot for the `AsyncDataComponent` (which has an `await` call in its `script setup`) and a `#fallback` slot that displays a loading state. While `AsyncDataComponent` resolves its promise (simulated 2-second delay), the fallback content is shown. Once resolved, the `default` content replaces the fallback, enhancing user experience during loading times.