Skip to content

Componentes Assíncronos

Uso Básico

Em grandes aplicações, podemos precisar dividir a aplicação em partes menores e apenas carregar um componente do servidor quando for necessário. Para possibilitar isto, a Vue tem uma função defineAsyncComponent:

js
import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() => {
  return new Promise((resolve, reject) => {
    // ...carregar o componente do servidor
    resolve(/* componente carregado */)
  })
})
// ... usar `AsyncComp` como um componente normal

Como podemos ver, defineAsyncComponent aceita uma função carregadora que retorna uma promessa. A função de resposta resolve da promessa deve ser chamada quando tivermos recuperado a definição da nosso componente do servidor. Nós também podemos chamar reject(reason) para indicar que o carregamento falhou.

A importação dinâmica do módulo da ECMAScript também retorna uma promessa, então na maioria das vezes a usaremos em conjunto com a defineAsyncComponent. As empacotadoras como a Vite e Webpack também suportam a sintaxe (e a usarão como pontos de separação do pacote), assim podemos usá-la para importar os componentes de ficheiro único da Vue:

js
import { defineAsyncComponent } from 'vue'

const AsyncComp = defineAsyncComponent(() =>
  import('./components/MyComponent.vue')
)

O AsyncComp resultante é um componente embrulhador que só chama a função carregadora quando estiver realmente desenhada na página. Além disto, este passará adiante quaisquer propriedades e ranhuras ao componente interno, assim podemos usar o embrulhador assíncrono para substituir perfeitamente o componente original enquanto realizamos o carregamento preguiçoso.

Tal como acontece com os componentes normais, os componentes assíncronos podem ser registados globalmente usando app.component():

js
app.component('MyComponent', defineAsyncComponent(() =>
  import('./components/MyComponent.vue')
))

Nós também podemos usar a defineAsyncComponent quando estivermos registando um componente localmente:

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

export default {
  components: {
    AdminPage: defineAsyncComponent(() =>
      import('./components/AdminPageComponent.vue')
    )
  }
}
</script>

<template>
  <AdminPage />
</template>

Estes também podem ser definidos diretamente dentro do seu componente pai:

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

const AdminPage = defineAsyncComponent(() =>
  import('./components/AdminPageComponent.vue')
)
</script>

<template>
  <AdminPage />
</template>

Estados de Carregamento e Erro

As operações assíncronas envolvem inevitavelmente os estados de carregamento e erro — a defineAsyncComponent() suporta a manipulação destes estados através das opções avançadas:

js
const AsyncComp = defineAsyncComponent({
  // a função carregadora
  loader: () => import('./Foo.vue'),

  // Um componente a usar enquanto o
  // componente assíncrono carrega
  loadingComponent: LoadingComponent,
  // Espera antes de exibir o componente de
  // carregamento. Predefinido como: 200ms
  delay: 200,

  // Um componente a usar se o carregamento falhar
  errorComponent: ErrorComponent,
  // O componente de erro será exibido se uma pausa for
  // fornecida e excedida Predefinida como: Infinity
  timeout: 3000
})

Se um componente de carregamento for fornecido, este será exibido primeiro enquanto o componente interno estiver sendo carregado. Existe um atraso de 200ms predefinido antes do componente de carregamento ser mostrado — isto porque nas redes rápidas, um estado de carregamento instantâneo pode ser substituído muito rápido e acabar por parecer-se como uma tremulação.

Se um componente de erro for fornecido, este será exibido quando a promessa retornada pela função carregadora for rejeitada. Nós também podemos especificar uma pausa para mostrar o componente de erro quando a requisição estiver a demorar muito.

Usar com Suspense

Os componentes assíncronos podem ser usados com o componente embutido <Suspense>. A interação entre os componentes <Suspense> e assíncronos é documentada no capítulo dedicado ao <Suspense>.

Componentes Assíncronos has loaded