You are browsing Nuxt 2 docs. Go to Nuxt 3 docs, or learn more about Nuxt 2 Long Term Support.

Translated page Contents of this page might be outdated.

Requisição de Dados

Dentro do Nuxt, nós temos duas maneiras de receber dados de uma API. Podemos usar o método fetch ou o método asyncData.


O Nuxt suporta os padrões tradicionais do Vue para o carregamento de dados em sua aplicação no lado do cliente, tais como requisição de dados dentro de um gatilho mounted() do componente. As aplicações universais, por outro lado, precisam usar gatilhos específicos do Nuxt para serem capazes de renderizar dados durante a renderização no lado do servidor. Isto permite a sua página renderizar com todos os seus dados obrigatórios presente.

O Nuxt tem dois gatilhos para carregamento assíncrono de dados:

  • asyncData. Este gatilho só pode ser colocado nos componentes page. Ao contrário do fetch, este gatilho não exibindo um placeholder de carregamento durante a renderização no lado do cliente: ao invés disso, este gatilho bloqueia a navegação da rota até estiver resolvida, exibindo uma página de erro se ele falhar.
  • fetch (Nuxt 2.12+). Este gatilho pode ser colocado em qualquer componente, e fornece atalhos para renderização para estados do carregamentos (durante a renderização no lado do cliente) e erros.

Estes gatilhos podem ser usados com qualquer biblioteca de requisição de dados que você escolher. Nós recomendamos usar @nuxt/http ou @nuxt/axios para fazer requisições para APIs em HTTP. Mais informações sobre estas bibliotecas, tais como guias para configuração de cabeçalhos de autenticação, podem ser achadas em suas respetivas documentações.

Se você definer fetch ou asyncData dentro de um mixin e também tem ele definido dentro de uma página/componente, a função mixin será sobrescrita ao invés de ser chamada.

O Gatilho Fetch

Antes do Nuxt 2.12, havia um gatilho fetch diferente que só funcionava para componentes page e não tinha acesso a instância do componente.Se o seu fetch() aceitar um argumento context, ele será tratado como um gatilho fetch legado. Esta funcionalidade está depreciada, e deve ser substituídos tanto com o asyncData ou um intermediário anónimo .

fetch é um gatilho chamado durante a renderização no lado do cliente depois da instância do componente ser criada, e no cliente quando estiver navegando. O gatilho fetch deve retornar uma promessa (seja explicitamente, ou implicitamente usando async/await) que será resolvida:

  • No servidor, antes da página inicial ser renderizada
  • No cliente, algum tempo depois que o componente ser montado
Para hospedagem estática , o gatilho fetch é somente chamado durante a geração da página, e o resultado é depois cacheado para ser usado no cliente. Para evitar conflitos, pode ser necessário especificar um nome para o seu componente, ou alternativamente fornecer uma implementação única fetchKey.

Uso

Requisitando Dados

Dentro do gatilho fetch, você terá acesso a instância do componente via this.

Certifique-se de que quaisquer propriedades que você queira modificar tenha já sido declarada dentro do data(). Então os dados que vierem da requisição possam ser atribuídas a essas propriedades.

Mudando o Comportamento do Fetch

fetchOnServer: Boolean ou Function (padrão: true), chama fetch() sempre que estiver renderizando a página no lado do servidor

fetchKey: String ou Function (padrões para o escopo ID do componente ou nome do componente), uma chave (ou uma função que produz uma chave única) que identifica o resultado deste fetch do componente (disponível no Nuxt 2.15+). Sempre que estiver hidratando uma página renderizada no lado do servidor, esta chave é será para mapear o resultado do fetch() no lado do servidor para os dados do componente no lado do cliente. Mais informações estão disponíveis dentro do PR original

fetchDelay: Integer (padrão: 200), define o tempo mínimo de execução em milissegundos (para evitar piscadas)

Sempre que o fetchOnServer for falsy (false ou retorna false), fetch será chamado somente no lado do cliente e $fetchState.pending retornará true quando estiver renderizando o componente no lado do servidor.

export default {
  data: () => ({
    posts: []
  }),
  async fetch() {
    this.posts = await this.$http.$get('https://api.nuxtjs.dev/posts')
  },
  fetchOnServer: false,
  // dois ou vários componentes podem retornar a mesma `fetchKey` e o Nuxt irá rastrear elas ambas separadamente
  fetchKey: 'site-sidebar',
  // alternativamente, para mais controle, uma função pode ser passado com acesso a instância do componente
  // Ele será chamado dentro do `created` e não deve depender dos dados requisitados
  fetchKey(getCounter) {
    // getCounter é um método que pode ser chamado para receber o próximo número dentro de uma sequência
    // como parte da geração de uma fetchKey única.
    return this.someOtherData + getCounter('sidebar')
  }
}

Acessando o Estado do Fetch

O gatilho fetch expõem this.$fetchState no nível do componente com as seguintes propriedades:

  • pending é um Boolean que permite você exibir um placeholder quando fetch estiver sendo chamado no lado do cliente.
  • error é um null ou um Error lançando pelo gatilho fetch
  • timestamp é uma referência a data e hora do ultimo fetch, útil para cacheamento com keep-alive

Adicionalmente ao fetch ser chamado pelo Nuxt, você pode manualmente chamar o fetch dentro do seu componente (para por exemplo recarregar seus dados assincronamente) ao chamar this.$fetch().

components/NuxtMountains.vue
<template>
  <div>
    <p v-if="$fetchState.pending">Fetching mountains...</p>
    <p v-else-if="$fetchState.error">An error occurred :(</p>
    <div v-else>
      <h1>Nuxt Mountains</h1>
      <ul>
        <li v-for="mountain of mountains">{{ mountain.title }}</li>
      </ul>
      <button @click="$fetch">Refresh</button>
    </div>
  </div>
</template>

<script>
  export default {
    data() {
      return {
        mountains: []
      }
    },
    async fetch() {
      this.mountains = await fetch(
        'https://api.nuxtjs.dev/mountains'
      ).then(res => res.json())
    }
  }
</script>
Você pode acessar o contexto do Nuxt dentro do gatilho fetch ao usar this.$nuxt.context.

Observando as Mudanças na Sequência de Caracteres de Consulta

O gatilho fetch não é chamado sobre as mudanças da string de consulta por padrão. Para vigiar as mudanças na consulta você pode adicionar um vigia sobre $route.query e depois chamar $fetch:

export default {
  watch: {
    '$route.query': '$fetch'
  },
  async fetch() {
    // Chamado também sobre as mudanças da consulta
  }
}

Cacheamento

Você pode usar a diretiva keep-alive dentro do componente <nuxt/> e <nuxt-child/> para guardar as chamados do fetch na páginas que você já visitou:

layouts/default.vue
<template>
  <nuxt keep-alive />
</template>

Você pode também especificar as props passadas para o <keep-alive> ao passar uma propriedade keep-alive-props para o componente <nuxt> :

layouts/default.vue
<nuxt keep-alive :keep-alive-props="{ max: 10 }" />

Mantenha apenas 10 componentes de página dentro da memória.

Manipulação de Erro

Se houver um erro durante a requisição dos dados, a página erro normal do Nuxt não será carregado - e você não deve usar o redirect do Nuxt ou o método error dentro do fetch(). Ao invés disso, você precisará manipular ele dentro do seu componente usando $fetchState.error.

Podemos verificar o $fetchState.error e exibir uma mensagem de erro se houver um erro na requisição dos dados.

components/MountainsList.vue
<template>
  <div>
    <p v-if="$fetchState.pending">Loading....</p>
    <p v-else-if="$fetchState.error">Error while fetching mountains</p>
    <ul v-else>
      <li v-for="(mountain, index) in mountains" :key="index">
        {{ mountain.title }}
      </li>
    </ul>
  </div>
</template>
<script>
  export default {
    data() {
      return {
        mountains: []
      }
    },
    async fetch() {
      this.mountains = await fetch(
        'https://api.nuxtjs.dev/mountains'
      ).then(res => res.json())
    }
  }
</script>

Usando o gatilho activated

O Nuxt irá diretamente preencher o this.$fetchState.timestamp (data e hora) do última chamada do fetch (inclusive no SSR). Você pode usar esta propriedade combinada com o gatilho activated para adicionar um cache de 30 segundos para fetch:

pages/posts/_id.vue
<template> ... </template>

<script>
  export default {
    data() {
      return {
        posts: []
      }
    },
    activated() {
      // Chama o fetch novamente se o último fetch foi a mais de 30 segundos atrás.
      if (this.$fetchState.timestamp <= Date.now() - 30000) {
        this.$fetch()
      }
    },
    async fetch() {
      this.posts = await fetch('https://api.nuxtjs.dev/posts').then(res =>
        res.json()
      )
    }
  }
</script>

A navegação para a mesma página não chamará o fetch se a última chamada do fetch antes de 30 segundos atrás.

Dados Assíncronos

asyncData está apenas disponível para páginas e você não tem acesso ao this dentro do gatilho.

asyncData é outro gatilho para requisição de dados universal. Ao contrário do fetch, que requer que você defina propriedades na instância do componente (ou despachar ações do Vuex) para guardar seu estado assíncrono, asyncData simplesmente funde seu valor de retorno dentro do seu estado local do componente. Aqui está um exemplo usando a biblioteca @nuxt/http :

pages/posts/_id.vue
<template>
  <div>
    <h1>{{ post.title }}</h1>
    <p>{{ post.description }}</p>
  </div>
</template>

<script>
  export default {
    async asyncData({ params, $http }) {
      const post = await $http.$get(`https://api.nuxtjs.dev/posts/${params.id}`)
      return { post }
    }
  }
</script>

Ao contrário do fetch, a promessa retornada pelo gatilho asyncData é resolvida durante a transição da rota. Isto significa que nenhum "placeholder de carregamento" está visível durante as transições do lado do cliente (se bem que a barra de carregamento pode ser usada para indicar um estado de carregamento ao usuário). O Nuxt irá ao invés disso esperar que o asyncData seja terminado antes de navegar para a próxima página ou exibir a página de erro .

Este gatilho pode somente ser usado para componentes do nível de página. Ao contrário do fetch, asyncData não consegue acessar a instância do componente (this). Ao invés disso, ele recebe o contexto como seu argumento. Você pode usar ele para pedir alguns dados e o Nuxt irá automaticamente fazer uma fusão superficial do objeto retornado com os dados do componente.

Dentro dos exemplos que estão por vir, estamos usando o @nuxt/http o qual recomendamos para requisição de dados de uma API.

Dados Assíncrono em Componentes?

Visto que os componentes não têm um método asyncData, você não consegue diretamente pedir dados assíncronos do lado do servidor dentro de um componente. No sentido de dar a volta a está limitação você tem três opções básicas:

  1. Usar o novo gatilho fetch que está disponível no Nuxt 2.12 e posteriores versões.
  2. Fazer a API chamar dentro do gatilho mounted e definir propriedades de dados sempre que for carregado. Desvantagem: Não funcionará para a renderização no lado do servidor
  3. Fazer a API chamar dentro do método asyncData do componente da página e passar os dados como propriedades para os subcomponentes. Funcionará bem no lado do servidor. Desvantagem: o asyncData da página pode ser menos legível porque está carregando os dados para outros componentes.

Ouvindo Mudanças na Consulta

O método asyncData não é chamado sobre as mudanças da string de consulta por padrão. Se você quiser mudar este comportamento, por exemplo quando estiver construindo um componente de paginação, você pode configurar parâmetros que devem ser ouvidos com a propriedade watchQuery do seu componente de página.

A propriedade watchQuery não funcionará apropriadamente para sítios gerados estáticos. Para fazer isso funcionar use o gatilho fetch e observe as mudanças na sequência de caracteres de consulta .