JAVASCRIPT
Vue 3 Suspense for Asynchronous Component Loading
Optimize user experience by implementing Vue 3's `Suspense` component to gracefully handle loading states for asynchronous components with fallback content.
// components/AsyncDataDisplay.vue
<template>
<div class="async-data-container">
<h3>Loaded Data</h3>
<p v-if="data">{{ data.value }}</p>
<p v-else>No data loaded yet.</p>
</div>
</template>
<script setup>
import { ref } from 'vue';
// Simulate an async operation
const data = ref(null);
await new Promise(resolve => {
setTimeout(() => {
data.value = 'Data successfully loaded after 2 seconds!';
resolve();
}, 2000);
});
</script>
<style scoped>
.async-data-container {
border: 1px dashed #ccc;
padding: 15px;
margin-top: 20px;
background-color: #f9f9f9;
}
</style>
// App.vue (Parent Component)
<template>
<div>
<h1>Welcome to My App</h1>
<p>This is some content above the async component.</p>
<!-- Using Suspense to handle the loading state of AsyncDataDisplay -->
<Suspense>
<!-- Content to display once AsyncDataDisplay is resolved -->
<template #default>
<AsyncDataDisplay />
</template>
<!-- Content to display while AsyncDataDisplay is pending (e.g., loading spinner) -->
<template #fallback>
<div class="loading-state">
<p>Loading async data, please wait...</p>
<div class="spinner"></div>
</div>
</template>
</Suspense>
<p style="margin-top: 20px;">This is some content below the async component.</p>
</div>
</template>
<script setup>
import { defineAsyncComponent } from 'vue';
// Define the component as an async component
const AsyncDataDisplay = defineAsyncComponent(() =>
import('./components/AsyncDataDisplay.vue')
);
</script>
<style>
.loading-state {
padding: 15px;
border: 1px solid #ddd;
background-color: #eef;
margin-top: 20px;
text-align: center;
}
.spinner {
border: 4px solid rgba(0, 0, 0, 0.1);
width: 30px;
height: 30px;
border-radius: 50%;
border-left-color: #09f;
animation: spin 1s ease infinite;
margin: 10px auto;
}
@keyframes spin {
to { transform: rotate(360deg); }
}
</style>
How it works: This snippet demonstrates Vue 3's `Suspense` component for managing asynchronous component loading and their loading states. `AsyncDataDisplay.vue` is an asynchronous component that uses `await` in its `setup` function to simulate a data fetching delay. The parent `App.vue` wraps this async component with `<Suspense>`, using the `#default` slot for the component once it's resolved, and the `#fallback` slot to display loading content (e.g., a spinner) while the async component is pending. This provides a clean way to handle loading UI for parts of your application that depend on asynchronous operations, improving user experience.