# Dinâmicos & Assíncronos

Essa página assume que você já leu o Básico sobre Componentes. Leia lá primeiro se você for novo em componentes.

# Componentes Dinâmicos com keep-alive

Anteriormente, usamos o atributo is para alternar entre os componentes em uma interface com guias:

<component :is="currentTabComponent"></component>
1

Ao alternar entre esses componentes, às vezes, você desejará manter seu estado ou evitar uma nova renderização, por motivos de desempenho. Por exemplo, ao expandir nossa interface com guias um pouco:

Veja o exemplo Componentes Dinâmicos: sem keep-alive por vuejs-br (@vuejs-br) no CodePen.

Você notará que, se selecionar uma postagem, alternar para a guia Arquivo e, em seguida, voltar para Postagens, ela não estará mais mostrando a postagem selecionada. Isso acontece pois, cada vez que você muda para uma nova guia, o Vue cria uma nova instância do componente currentTabComponent.

Recriar componentes dinâmicos normalmente é um comportamento útil, mas, nesse caso, gostaríamos que essas instâncias de componentes de guias fossem armazenadas em cache assim que fossem criadas pela primeira vez. Para resolver este problema, podemos envolver nosso componente dinâmico com um elemento <keep-alive>:

<!-- Componentes inativos serão armazenados em cache -->
<keep-alive>
  <component :is="currentTabComponent"></component>
</keep-alive>
1
2
3
4

Confira o resultado abaixo:

Veja o exemplo Componentes Dinâmicos: com keep-alive por vuejs-br (@vuejs-br) no CodePen.

Agora, a guia Postagens mantém seu estado (a postagem selecionada) mesmo quando não é renderizada.

Confira mais detalhes sobre <keep-alive> em Referências de API.

# Componentes Assíncronos

Em aplicativos grandes, talvez seja necessário dividí-lo em partes menores e carregar apenas um componente do servidor quando necessário.. Para tornar isso possível, o Vue tem o método defineAsyncComponent:

const { createApp, defineAsyncComponent } = Vue

const app = createApp({})

const AsyncComp = defineAsyncComponent(
  () =>
    new Promise((resolve, reject) => {
      resolve({
        template: '<div>Eu sou assíncrono!</div>',
      })
    })
)

app.component('async-example', AsyncComp)
1
2
3
4
5
6
7
8
9
10
11
12
13
14

Como você pode ver, esse método aceita uma função de fabricação (factory function) que retorna uma Promise. O retorno de chamada resolve da Promise deve ser chamado quando você recuperar sua definição de componente do servidor. Você também pode chamar reject(reason) para indicar que o carregamento falhou.

Você também pode retornar uma Promise na função de fabricação. Portanto, com a sintaxe do Webpack 2+ ou ES2015, você pode fazer:

import { defineAsyncComponent } from 'vue'

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

app.component('async-component', AsyncComp)
1
2
3
4
5
6
7

Você também pode usar o defineAsyncComponent ao registrar um componente localmente:

import { createApp, defineAsyncComponent } from 'vue'

createApp({
  // ...
  components: {
    AsyncComponent: defineAsyncComponent(() =>
      import('./components/AsyncComponent.vue')
    ),
  },
})
1
2
3
4
5
6
7
8
9
10

# Usando com Suspense

Os componentes assíncronos são suspensos por padrão. Isso significa que, se houver um <Suspense> na na hierarquia pai, ele será tratado como uma dependência assíncrona deste <Suspense>. Nesse caso, o estado de carregamento será controlado pelo <Suspense>, e as opções de carregamento, gatilho de erros, atrasos e tempo limite do próprio componente serão ignoradas.

O componente assíncrono pode cancelar o controle do Suspense e deixar que o componente sempre controle seu próprio estado de carregamento, especificando suspensible: false em suas opções.

Você pode conferir a lista de opções disponíveis na Referência da API