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 dofetch
, 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.
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
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
Uso
Requisitando Dados
Dentro do gatilho fetch, você terá acesso a instância do componente via this
.
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
é umBoolean
que permite você exibir um placeholder quandofetch
estiver sendo chamado no lado do cliente. -
error
é umnull
ou umError
lançando pelo gatilho fetch -
timestamp
é uma referência a data e hora do ultimo fetch, útil para cacheamento comkeep-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()
.
<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>
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:
<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>
:
<nuxt keep-alive :keep-alive-props="{ max: 10 }" />
Mantenha apenas 10 componentes de página dentro da memória.
Manipulação de Erro
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.
<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
:
<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
é 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 :
<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:
-
Usar o novo gatilho
fetch
que está disponível no Nuxt 2.12 e posteriores versões. -
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 -
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: oasyncData
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.
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 .