nuxt

03 dez 2024

useAsyncData ou useLazyAsyncData, qual usar?

No Nuxt, esses dois composables são responsáveis por buscar dados via SSR e exibir a informação em tela, porém existe uma diferença chave entre eles.

O useAsyncData bloqueia a navegação até o dado ser resolvido, ou seja, a troca de página não acontece até que tudo esteja conforme o esperado.

Dica: usar o componente NuxtLoadingIndicator é uma maneira simples de mostrar esse estado de loading para o usuário.

Já o useLazyAsyncData não faz o bloqueio da navegação, dessa forma, precisamos tratar o estado de loading na tela com base no estado de “status” (retornado pelo composable), seja com um skeleton ou algum outro loader.

Veja um exemplo do uso desses dois composables:

useAsyncData

<script setup lang="ts">
// useAsyncData
const { data: posts } = await useAsyncData("posts", () =>
  $fetch("https://jsonplaceholder.typicode.com/posts/")
)
</script>

<template>
  <ul>
    <li v-for="post in posts" :key="post.id">
      <h3>{{ post.title }}</h3>
    </li>
  </ul>
</template>

useLazyAsyncData

<script setup lang="ts">
// useLazyAsyncData
const { status, data: todos } = await useLazyAsyncData("todos", () =>
  $fetch("https://jsonplaceholder.typicode.com/todos")
)
</script>

<template>
  <ListLoader v-if="status === 'pending'" />

  <ul v-else>
    <li v-for="post in posts" :key="post.id">
      <h3>{{ post.title }}</h3>
    </li>
  </ul>
</template>

Em ambos os casos temos a renderização por parte do servidor se a página for diretamente acessada, ou seja, não temos perdas em termos de SEO. Essa sempre foi minha maior dúvida. Podemos validar isso na aba "payload”, dentro do devtools.

Então, qual a diferença entre eles? A resposta: UX.

A preferência vai do desenvolvedor (ou do designer). Pensando como usuário, eu particularmente prefiro o useLazyAsyncData e uma tela de loading e torna a navegação muito mais fluida. No entanto, essa abordagem é um pouco mais trabalhosa e demorada.

Confira mais exemplos e o guia completo de uso na documentação oficial.