← Back to all snippets
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.

Need help integrating this into your project?

Our team of expert developers can help you build your custom application from scratch.

Hire DigitalCodeLabs