Dinâmicos & Assíncronos

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

Componentes Dinâmicos com keep-alive

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

<component v-bind:is="currentTabComponent"></component>

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

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 v-bind:is="currentTabComponent"></component>
</keep-alive>

Confira o resultado abaixo:

Agora, a guia Postagens mantém seu estado (a postagem selecionada) mesmo quando não é renderizada. Veja este exemplo para o código completo.

Perceba que o <keep-alive> requer que todos os componentes que estejam sendo trocados tenham nomes, seja usando a opção name do componente, seja através de registro local/global.

Confira mais detalhes sobre o <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 isto mais fácil, o Vue permite que você defina seu componente como uma função de fabricação (factory function), que resolve de forma assíncrona sua definição de componente. O Vue só acionará a função quando o componente precisar ser renderizado, e armazenará em cache o resultado para novas renderizações futuras. Por exemplo:

Vue.component('async-example', function (resolve, reject) {
setTimeout(function () {
// Passa a definição do componente para resolver o callback
resolve({
template: '<div>I am async!</div>'
})
}, 1000)
})

Como você pode ver, a função de fabricação recebe um retorno de chamada resolve, que 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. O setTimeout aqui é meramente para demonstração; como recuperar o componente é com você. Uma abordagem recomendada é usar componentes assíncronos junto com o recurso de divisão de código do Webpack:

Vue.component('async-webpack-example', function (resolve) {
// Esta sintaxe especial com `require` irá instruir o Webpack
// a automaticamente dividir seu pacote em pedaços, os quais
// serão carregados através de requisições Ajax.
require(['./my-async-component'], resolve)
})

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

Vue.component(
'async-webpack-example',
// A função `import` retorna uma Promise.
() => import('./my-async-component')
)

Ao usar o registro local de componentes, você também pode fornecer diretamente uma função que retorna uma Promise:

new Vue({
// ...
components: {
'my-component': () => import('./my-async-component')
}
})

Se você é um usuário do Browserify e gostaria de usar componentes assíncronos, seu criador infelizmente deixou claro que o carregamento assíncrono “não é algo que o Browserify irá suportar”. Oficialmente, pelo menos. A comunidade Browserify encontrou algumas soluções alternativas, que podem ser úteis para aplicativos existentes e complexos. Para todos os outros cenários, recomendamos o uso do Webpack para suporte assíncrono integrado de primeira classe.

Manipulando Estado de Carregamento

Novidade na versão 2.3.0+

A função de fábrica de componentes assíncronos também pode retornar um objeto no seguinte formato:

const AsyncComponent = () => ({
// O componente a carregar (deve ser uma Promise)
component: import('./MyComponent.vue'),
// Um componente para usar enquanto o assíncrono é carregado
loading: LoadingComponent,
// Um componente para usar se o carregamento falhar
error: ErrorComponent,
// Espera antes de exibir o componente de loading. Padrão: 200ms
delay: 200,
// O componente de erro será exibido se um timemout for
// fornecido e excedido. Padrão: Infinity
timeout: 3000
})

Note que você precisa utilizar o vue-router 2.4.0+ se você quiser usar a sintaxe acima para componentes de rota.