0Pricing
Vue Academy · Aula

Componente Vue Suspense

com slots default e #fallback, carregamento de componentes assíncronos e Suspense aninhado.

Componente Vue Suspense é uma aula grátis de Vue Academy no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de Vue Academy, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de Vue Academy inclui 4 aulas no total.

O que Suspense resolve

Suspense é um componente integrado do Vue que coordena os estados de carregamento de componentes que têm dependências assíncronas.

Sem ele, cada componente assíncrono gerencia seu próprio indicador de carregamento. Com Suspense, você declara um único limite que aguarda todo o trabalho assíncrono aninhado e exibe um único fallback até que tudo esteja pronto.

Duas áreas: default e fallback

Suspense expõe duas áreas nomeadas:

  • default — o conteúdo real, que pode conter componentes assíncronos ou um setup() assíncrono
  • fallback — o que deve ser exibido enquanto a área default é resolvida

Quando todas as dependências assíncronas são resolvidas, o Vue substitui o fallback pelo conteúdo default.

<template>
  <Suspense>
    <template #default>
      <UserDashboard />
    </template>
    <template #fallback>
      <div class="spinner">Loading dashboard...</div>
    </template>
  </Suspense>
</template>

setup() assíncrono como dependência

Um componente se torna uma dependência assíncrona quando sua função setup() é declarada como async e aguarda algo. O Vue acompanha a promessa retornada.

O equivalente de <script setup> é usar await diretamente no nível superior dentro do bloco.

<script setup>
import { ref } from 'vue'

// Top-level await makes this an async dependency of Suspense
const res = await fetch('/api/profile')
const profile = ref(await res.json())
</script>

<template>
  <h1>Welcome, {{ profile.name }}</h1>
</template>

Componentes assíncronos também contam

Os componentes criados com defineAsyncComponent também são acompanhados pelo Suspense. O fallback permanece visível até que a import() dinâmica seja resolvida.

Isso permite dividir o código de componentes pesados em partes sem escrever uma interface de carregamento para cada componente.

<script setup>
import { defineAsyncComponent } from 'vue'

const Chart = defineAsyncComponent(() =>
  import('./HeavyChart.vue')
)
</script>

<template>
  <Suspense>
    <Chart />
    <template #fallback>Preparing chart...</template>
  </Suspense>
</template>

Vários filhos assíncronos aguardam juntos

Se o slot padrão contiver várias dependências assíncronas, Suspense aguardará a resolução de todas elas antes de revelar o conteúdo.

Isso evita mudanças de layout causadas pela entrada dos componentes um de cada vez.

<template>
  <Suspense>
    <div>
      <UserStats />   <!-- async setup -->
      <RecentOrders /> <!-- async setup -->
      <Recommendations /> <!-- async component -->
    </div>
    <template #fallback>
      <PageSkeleton />
    </template>
  </Suspense>
</template>

Capturando rejeições com onErrorCaptured

Se um setup() assíncrono for rejeitado (por exemplo, devido a uma busca malsucedida), o erro será propagado até o hook onErrorCaptured mais próximo em um componente pai.

O próprio Suspense não renderiza erros, portanto combine-o com um limite de erros.

<script setup>
import { ref, onErrorCaptured } from 'vue'

const error = ref(null)

onErrorCaptured((err) => {
  error.value = err
  return false // stop the error from propagating further
})
</script>

Padrão de limite de erros + Suspense

O padrão comum em produção envolve o Suspense em um componente de limite de erros. onErrorCaptured retorna false para interromper a propagação e renderizar uma interface de erro.

<script setup>
import { ref, onErrorCaptured } from 'vue'
const err = ref(null)
onErrorCaptured((e) => { err.value = e; return false })
</script>

<template>
  <p v-if="err">Failed to load: {{ err.message }}</p>
  <Suspense v-else>
    <ProfilePanel />
    <template #fallback>Loading...</template>
  </Suspense>
</template>

Os eventos pending e resolve

Suspense emite eventos do ciclo de vida aos quais você pode reagir:

  • @pending — disparado ao entrar em um estado pendente (carregamento)
  • @resolve — disparado quando o slot padrão termina de ser resolvido
  • @fallback — disparado quando o conteúdo alternativo é exibido

Útil para análise de dados ou barras de progresso.

<template>
  <Suspense @pending="onPending" @resolve="onResolve">
    <RouteView />
    <template #fallback>Loading route...</template>
  </Suspense>
</template>

A propriedade timeout para conteúdo alternativo atrasado

A propriedade timeout (em milissegundos) atrasa a exibição do conteúdo alternativo. Se o trabalho assíncrono for resolvido antes desse tempo, o conteúdo alternativo nunca será exibido.

Isso evita que um indicador de carregamento pisque em respostas rápidas.

<template>
  <!-- Only show fallback if loading exceeds 200ms -->
  <Suspense :timeout="200">
    <FastPanel />
    <template #fallback>Loading...</template>
  </Suspense>
</template>

Suspense com Router e transições

Suspense pode ser combinado com RouterView e Transition para animar mudanças assíncronas de rota. A ordem é importante: Transition envolve Suspense, que envolve o componente roteado.

<template>
  <RouterView v-slot="{ Component }">
    <Transition mode="out-in">
      <Suspense>
        <component :is="Component" />
        <template #fallback>Loading page...</template>
      </Suspense>
    </Transition>
  </RouterView>
</template>

Quando NÃO usar Suspense

Evite Suspense para dados que são buscados novamente com frequência enquanto o componente permanece montado — ele governa apenas a resolução assíncrona inicial. Para estados de carregamento contínuo (paginação, nova busca), use uma ref reativa normal de loading.

<script setup>
import { ref } from 'vue'
const loading = ref(false)
async function loadMore() {
  loading.value = true
  await fetchNextPage()
  loading.value = false
}
</script>

Verificação rápida

Teste sua compreensão de Suspense.

Recapitulação

Você aprendeu como Suspense coordena dependências assíncronas:

  • o slot padrão contém conteúdo assíncrono (configuração assíncrona ou componentes assíncronos)
  • o slot de conteúdo alternativo é exibido durante o carregamento
  • aguarda todos os filhos assíncronos antes de revelar o conteúdo
  • as rejeições chegam a onErrorCaptured no limite de erros de um componente pai
  • timeout evita que o indicador de carregamento pisque; eventos como @resolve ajudam na análise de dados

Perguntas Frequentes

A aula “Componente Vue Suspense” é grátis?

Sim — o texto completo de “Componente Vue Suspense” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de Vue Academy, atualize para CoddyKit PRO. O curso de Vue Academy inclui 4 aulas no total.

O que vou aprender em “Componente Vue Suspense”?

com slots default e #fallback, carregamento de componentes assíncronos e Suspense aninhado. Você pratica Vue Academy com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar Vue Academy?

Nenhuma experiência prévia é necessária. Vue Academy no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Componente Vue Suspense”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de Vue Academy?

Sim. Cada aula de Vue Academy inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Componente Vue Suspense
  2. Componentes assíncronos com defineAsyncComponent
  3. SSR em fluxo com renderToWebStream
  4. Estratégias de hidratação adiada
← Voltar para Vue Academy