Introdução ao Axios no Nuxt
Publicados: 2022-03-10ayncData
e fetch
para buscar dados no lado do servidor usando o Axios e as diferenças entre os dois métodos. Por fim, aprenderemos como adicionar autenticação ao nosso aplicativo usando o módulo Auth.Nuxt.js fornece um módulo Axios para fácil integração com seu aplicativo. O Axios é um cliente HTTP baseado em promessas que funciona no navegador e no ambiente Node.js ou, em termos mais simples, é uma ferramenta para fazer solicitações (por exemplo, chamadas de API) em aplicativos do lado do cliente e no ambiente Node.js.
Neste tutorial, vamos aprender como usar o módulo Axios e como fazer uma solicitação no lado do servidor usando asyncData e fetch. Esses dois métodos fazem uma solicitação no lado do servidor, mas têm algumas diferenças que também abordaremos. Por fim, aprenderemos como realizar autenticação e proteger páginas/rotas usando o módulo de autenticação e o middleware de autenticação.
Este artigo requer conhecimento básico de Nuxtjs e Vuejs, pois estaremos construindo em cima disso. Para aqueles sem experiência com Vuejs, recomendo que você comece pela documentação oficial e pela página oficial do Nuxt antes de continuar com este artigo.
O que é o módulo Axios Nuxt.js?
De acordo com a documentação oficial,
“É uma integração segura e fácil do Axios com o Nuxt.js.”
Aqui estão algumas de suas características:
- Defina automaticamente a URL base para o lado do cliente e o lado do servidor.
- Cabeçalhos de solicitação de proxy em SSR (útil para autenticação).
- Buscar solicitações de estilo.
- Integrado com Nuxt.js Progressbar ao fazer solicitações.
Para usar o módulo axios em seu aplicativo, primeiro você terá que instalá-lo usando npm
ou yarn
.
FIO
yarn add @nuxtjs/axios
NPM
npm install @nuxtjs/axios
Adicione-o ao seu arquivo nuxt.config.js
:
modules: [ '@nuxtjs/axios', ], axios: { // extra config eg // BaseURL: 'https://link-to-API' }
A matriz de modules
aceita uma lista de módulos Nuxt.js, como dotenv, auth e, neste caso, Axios. O que fizemos foi informar ao nosso aplicativo que usaríamos o módulo Axios, que referenciamos usando @nuxtjs/axios
. Isso é seguido pela propriedade axios
, que é um objeto de configurações como o baseURL para o lado do cliente e o lado do servidor.
Agora, você pode acessar o Axios de qualquer lugar em seu aplicativo chamando this.$axios.method
ou this.$axios.$method
. Onde o método pode ser get
, post
ou delete
.
Fazendo sua primeira solicitação usando o Axios
Para este tutorial, montei um aplicativo simples no Github. O repositório contém duas pastas, iniciar e terminar, a pasta inicial contém tudo que você precisa para ir direto ao tutorial. A pasta de acabamento contém uma versão completa do que estaríamos construindo.
Após clonar o repositório e abrir a pasta start
, precisaríamos instalar todos os nossos pacotes no arquivo package.json
, então abra seu terminal e execute o seguinte comando:
npm install
Feito isso, podemos iniciar nosso aplicativo usando o comando npm run dev
. Isto é o que você deve ver quando for para localhost:3000
.

A próxima coisa que temos que fazer é criar um arquivo .env
na pasta raiz de nosso aplicativo e adicionar nossa URL de API a ele. Para este tutorial, usaremos uma API de exemplo criada para coletar relatórios dos usuários.
API_URL=https://ireporter-endpoint.herokuapp.com/api/v2/
Dessa forma, não precisamos codificar nossa API em nosso aplicativo, o que é útil para trabalhar com duas APIs (desenvolvimento e produção).
O próximo passo seria abrir nosso arquivo nuxt.config.js
e adicionar a variável ambiental à nossa configuração axios que adicionamos acima.
/* ** Axios module configuration */ axios: { // See https://github.com/nuxt-community/axios-module#options baseURL: process.env.API_URL, },
Aqui, dizemos ao Nuxt.js para usar esse baseURL
para nossas solicitações do lado do cliente e do lado do servidor sempre que usarmos esse módulo Axios.
Agora, para buscar uma lista de relatórios, vamos abrir o arquivo index.vue
e adicionar o seguinte método à seção de script.
async getIncidents() { let res = await this.$store.dispatch("getIncidents"); this.incidents = res.data.data.incidents; }
O que fizemos foi criar uma função assíncrona que chamamos de getIncidents()
e podemos dizer o que ela faz pelo nome — ela busca uma lista de incidentes usando o método de ação da loja Vuex this.$store.dispatch
. Atribuímos a resposta dessa ação à nossa propriedade de incidentes para que possamos usá-la no componente.
Queremos chamar o método getIncidents()
sempre que o componente for montado. Podemos fazer isso usando o gancho mounted
.
mounted() { this.getIncidents() }
mounted()
é um gancho de ciclo de vida que é chamado quando o componente é montado. Isso fará com que a chamada para a API aconteça quando o componente for montado. Agora, vamos entrar em nosso arquivo index.js
em nossa loja e criar esta ação de onde faremos nossa solicitação do Axios.
export const actions = { async getIncidents() { let res = await this.$axios.get('/incidents') return res; } }
Aqui, criamos a ação chamada getIncidents
que é uma função assíncrona, então aguardamos uma resposta do servidor e retornamos essa resposta. A resposta desta ação é enviada de volta ao nosso método getIncidents()
em nosso arquivo index.vue
.
Se atualizarmos nosso aplicativo, agora poderemos ver uma longa lista de incidentes renderizados na página.

Fizemos nossa primeira solicitação usando o Axios, mas não vamos parar por aí, vamos experimentar o asyncData
e fetch
para ver as diferenças entre eles e o uso do Axios.
AsyncData
AsyncData busca dados no lado do servidor e é chamado antes de carregar o componente da página. Ele não tem acesso a this
porque é chamado antes da criação dos dados do componente da página. this
só está disponível após o gancho created
ter sido chamado, de modo que o Nuxt.js mescla automaticamente os dados retornados nos dados do componente.
O uso asyncData
é bom para SEO porque busca o conteúdo do seu site no lado do servidor e também ajuda a carregar o conteúdo mais rapidamente. Observe que o método asyncData
só pode ser usado na pasta de páginas do seu aplicativo, pois não funcionaria na pasta de componentes. Isso ocorre porque o gancho asyncData
é chamado antes que seu componente seja criado.

Vamos adicionar asyncData
ao nosso arquivo index.vue
e observar a rapidez com que nossos dados de incidentes são carregados. Adicione o código a seguir após nossa propriedade de componentes e vamos nos livrar de nosso gancho montado.
async asyncData({ $axios }) { let { data } = await $axios.get("/incidents"); return { incidents: data.data.incidents }; }, // mounted() { // this.getIncidents(); // },
Aqui, o método asyncData
aceita uma propriedade do contexto $axios
. Usamos essa propriedade para buscar a lista de incidentes e o valor é então retornado. Esse valor é injetado automaticamente em nosso componente. Agora, você pode notar o quão rápido seu conteúdo carrega se você atualizar a página e em nenhum momento não houver nenhum incidente para renderizar.
Buscar
O método Fetch também é usado para fazer solicitações no lado do servidor. Ele é chamado após o gancho criado no ciclo de vida, o que significa que ele tem acesso aos dados do componente. Ao contrário do método asyncData
, o método fetch pode ser usado em todos os arquivos .vue e com o armazenamento Vuex. Isso significa que, se você tiver o seguinte em sua função de dados.
data() { return { incidents: [], id: 5, gender: 'male' }; }
Você pode facilmente modificar id ou gênero chamando this.id
ou this.gender
.
Usando o Axios como um plugin
Durante o processo de desenvolvimento com o Axios, você pode descobrir que precisa de configuração extra, como criar instâncias e interceptores para sua solicitação, para que seu aplicativo funcione conforme o esperado e, felizmente, podemos fazer isso estendendo nosso Axios em um plug-in.
Para estender axios
, você precisa criar um plugin (por exemplo , axios.js ) na pasta de plugins
.
export default function ({ $axios, store, redirect }) { $axios.onError(error => { if (error.response && error.response.status === 500) { redirect('/login') } }) $axios.interceptors.response.use( response => { if (response.status === 200) { if (response.request.responseURL && response.request.responseURL.includes('login')) { store.dispatch("setUser", response); } } return response } ) }
Este é um exemplo de um plugin que escrevi para um aplicativo Nuxt. Aqui, sua função recebe um objeto de contexto $axios
, store
e redirect
que usaríamos na configuração do plugin. A primeira coisa que fazemos é escutar um erro com status 500
usando $axios.onError
e redirecionar o usuário para a página de login.
Também temos um interceptor que intercepta cada resposta de solicitação que fazemos em nosso aplicativo verifica se o status da resposta que recebemos é 200
. Se isso for verdade, continuamos e verificamos se existe um response.request.responseURL
e se inclui login. Se isso for verdade, enviaremos essa resposta usando o método dispatch de nossa loja, onde ela sofreu uma mutação em nosso estado.
Adicione este plug-in ao seu arquivo nuxt.config.js
:
plugins: [ '~/plugins/axios' ]
Depois de fazer isso, seu plug-in Axios interceptaria qualquer solicitação que você fizer e verificaria se você definiu um caso especial para ela.
Introdução ao módulo de autenticação
O módulo auth é usado para realizar autenticação para seu aplicativo Nuxt e pode ser acessado de qualquer lugar em seu aplicativo usando $this.auth
. Também está disponível em fetch
, asyncData
, middleware
e NuxtInitServer
do objeto de contexto como $auth
.
O context
fornece objetos/parâmetros adicionais dos componentes Nuxt para Vue e está disponível em áreas especiais do ciclo de vida do nuxt, como as mencionadas acima.
Para usar o módulo auth em seu aplicativo, você teria que instalá-lo usando yarn
ou npm
.
FIO
yarn add @nuxtjs/auth
NPM
npm install @nuxtjs/auth
Adicione-o ao seu arquivo nuxt.config.js
.
modules: [ '@nuxtjs/auth' ], auth: { // Options }
A propriedade auth aceita uma lista de propriedades como strategies
e redirect
. Aqui, strategies
aceitam seu método de autenticação preferido, que pode ser:
-
local
Para fluxo baseado em nome de usuário/e-mail e senha. -
facebook
Para usar contas do Facebook como meio de autenticação. -
Github
Para autenticar usuários com contas do Github. -
Google
Para autenticar usuários com contas do Google. - Aut0
- Passaporte Laravel
A propriedade de redirecionamento aceita um objeto de links para:
-
login
Os usuários serão redirecionados para este link se o login for necessário. -
logout
Os usuários serão redirecionados aqui se após o logout a rota atual estiver protegida. -
home
Os usuários seriam redirecionados aqui após o login.
Agora, vamos adicionar o seguinte ao nosso arquivo nuxt.config.js
.
/* ** Auth module configuration */ auth: { redirect: { login: '/login', logout: '/', home: '/my-reports' }, strategies: { local: { endpoints: { login: { url: "/user/login", method: "post", propertyName: "data.token", }, logout: false, user: false, }, tokenType: '', tokenName: 'x-auth', autoFetchUser: false }, }, }
Observe que o método de auth
funciona melhor quando há um endpoint de user
fornecido na opção acima.
Dentro do objeto de configuração auth
, temos uma opção de redirect
na qual definimos nossa rota de login para /login
, rota de logout para /
e rota inicial para /my-reports
que se comportariam conforme o esperado. Também temos uma propriedade tokenType
que representa o tipo de autorização no cabeçalho de nossa solicitação Axios. Ele é definido como Bearer
por padrão e pode ser alterado para funcionar com sua API.
Para nossa API, não existe um tipo de token e é por isso que vamos deixá-lo como uma string vazia. O tokenName
representa o nome de autorização (ou a propriedade de cabeçalho à qual você deseja anexar seu token) dentro de seu cabeçalho em sua solicitação do Axios.
Por padrão, está definido como Authorization
, mas para nossa API, o nome da Autorização é x-auth
. A propriedade autoFetchUser
é usada para ativar o objeto de busca do user
após o login. É true
por padrão, mas nossa API não possui um endpoint de user
, portanto, definimos isso como false
.
Para este tutorial, usaríamos a estratégia local. Em nossas estratégias, temos a opção local com endpoints para login, usuário e logout, mas no nosso caso, usaríamos apenas a opção *login*
porque nossa API de demonstração não possui um endpoint *logout*
e nosso objeto de usuário está sendo retornado quando *login*
é bem sucedido.
Nota: O módulo auth
não possui a opção de registrar endpoint, então isso significa que vamos registrar da maneira tradicional e redirecionar o usuário para a página de login onde realizaremos a autenticação usando this.$auth.loginWith
. Este é o método usado para autenticar seus usuários. Ele aceita uma 'estratégia' (por exemplo, local
) como primeiro argumento e depois um objeto para realizar essa autenticação. Dê uma olhada no exemplo a seguir.

let data { email: '[email protected]', password: '123456' } this.$auth.loginWith('local', { data })
Usando o módulo de autenticação
Agora que configuramos nosso módulo de autenticação, podemos prosseguir para nossa página de registro. Se você visitar a página /register
, deverá ver um formulário de registro.

Vamos tornar este formulário funcional adicionando o seguinte código:
methods: { async registerUser() { this.loading = true; let data = this.register; try { await this.$axios.post("/user/create", data); this.$router.push("/login"); this.loading = false; this.$notify({ group: "success", title: "Success!", text: "Account created successfully" }); } catch (error) { this.loading = false; this.$notify({ group: "error", title: "Error!", text: error.response ? error.response.data.error : "Sorry an error occured, check your internet" }); } } }
Aqui, temos uma função assíncrona chamada registerUser
que está vinculada a um evento de clique em nosso modelo e faz uma solicitação do Axios envolvida em um bloco try/catch para um endpoint /user/create
. Isso redireciona para a página /login
e notifica o usuário de um registro bem-sucedido. Também temos um bloco catch que alerta o usuário sobre qualquer erro caso a solicitação não seja bem-sucedida.
Se o registro for bem-sucedido, você será redirecionado para a página de login.

Aqui, vamos usar o método de autenticação de autenticação this.$auth.loginWith('local', loginData)
após o qual usaríamos o this.$auth.setUser(userObj)
para definir o usuário em nossa instância de auth
.
Para que a página de login funcione, vamos adicionar o seguinte código ao nosso arquivo login.vue
.
methods: { async logIn() { let data = this.login; this.loading = true; try { let res = await this.$auth.loginWith("local", { data }); this.loading = false; let user = res.data.data.user; this.$auth.setUser(user); this.$notify({ group: "success", title: "Success!", text: "Welcome!" }); } catch (error) { this.loading = false; this.$notify({ group: "error", title: "Error!", text: error.response ? error.response.data.error : "Sorry an error occured, check your internet" }); } } }
Criamos uma função assíncrona chamada logIn
usando o método de autenticação this.$auth.loginWith('local, loginData)
. Se essa tentativa de login for bem-sucedida, atribuímos os dados do usuário à nossa instância de autenticação usando this.$auth.setUser(userInfo)
e redirecionamos o usuário para a página /my-report
.
Agora você pode obter dados do usuário usando this.$auth.user
ou com Vuex usando this.$store.state.auth.user
, mas isso não é tudo. A instância de auth
contém algumas outras propriedades que você pode ver se fizer login ou verificar seu estado usando suas ferramentas de desenvolvimento Vue.
Se você registrar this.$store.state.auth
no console, verá isto:
{ "auth": { "user": { "id": "d7a5efdf-0c29-48aa-9255-be818301d602", "email": "[email protected]", "lastName": "Xo", "firstName": "Tm", "othernames": null, "isAdmin": false, "phoneNumber": null, "username": null }, "loggedIn": true, "strategy": "local", "busy": false } }
A instância auth
contém uma propriedade loggedIn
que é útil para alternar entre links autenticados na seção nav/header de seu aplicativo. Ele também contém um método de estratégia que indica o tipo de estratégia que a instância está executando (por exemplo, local).
Agora, usaremos essa propriedade loggedIn
para organizar nossos links de nav
. Atualize seu componente navBar
para o seguinte:
<template> <header class="header"> <div class="logo"> <nuxt-link to="/"> <Logo /> </nuxt-link> </div> <nav class="nav"> <div class="nav__user" v-if="auth.loggedIn"> <p>{{ auth.user.email }}</p> <button class="nav__link nav__link--long"> <nuxt-link to="/report-incident">Report incident</nuxt-link> </button> <button class="nav__link nav__link--long"> <nuxt-link to="/my-reports">My Reports</nuxt-link> </button> <button class="nav__link" @click.prevent="logOut">Log out</button> </div> <button class="nav__link" v-if="!auth.loggedIn"> <nuxt-link to="/login">Login</nuxt-link> </button> <button class="nav__link" v-if="!auth.loggedIn"> <nuxt-link to="/register">Register</nuxt-link> </button> </nav> </header> </template> <script> import { mapState } from "vuex"; import Logo from "@/components/Logo"; export default { name: "nav-bar", data() { return {}; }, computed: { ...mapState(["auth"]) }, methods: { logOut() { this.$store.dispatch("logOut"); this.$router.push("/login"); } }, components: { Logo } }; </script> <style></style>
Em nossa seção de modelo, temos vários links para diferentes partes do aplicativo no qual estamos usando agora auth.loggedIn
para exibir os links apropriados, dependendo do status de autenticação. Temos um botão de logout que possui um evento de click
com uma função logOut()
anexada a ele. Também exibimos o email do usuário obtido da propriedade auth que é acessada de nossa loja Vuex usando o método mapState
que mapeia nossa autenticação de estado para a propriedade computada do componente nav. Também temos um método de logout
que chama nossa ação logOut
e redireciona o usuário para a página de login
.
Agora, vamos em frente e atualizar nossa loja para ter uma ação logOut
.
export const actions = { // .... logOut() { this.$auth.logout(); } }
A ação logOut
chama o método auth logout
que limpa os dados do usuário, exclui tokens de localStorage
e define o loggedIn
como false
.
Rotas como /my-reports
e report-incident
não devem ser visíveis para os hóspedes , mas neste momento em nosso aplicativo, esse não é o caso. O Nuxt não possui um protetor de navegação que possa proteger suas rotas, mas possui o middleware de autenticação. Dá a você a liberdade de criar seu próprio middleware para que você possa configurá-lo para funcionar da maneira que desejar.
Pode ser definido de duas maneiras:
- Por rota.
- Globalmente para todo o aplicativo em seu arquivo
nuxt.config.js
.
router: { middleware: ['auth'] }
Esse middleware de auth
funciona com sua instância de auth
, portanto, você não precisa criar um arquivo auth.js
em sua pasta de middleware.
Vamos agora adicionar este middleware aos nossos arquivos my-reports.vue
e report-incident.vue
. Adicione as seguintes linhas de código à seção de script de cada arquivo.
middleware: 'auth'
Agora, nosso aplicativo verificaria se o usuário que tenta acessar essas rotas tem um valor auth.loggedIn
de true
. Ele irá redirecioná-los para a página de login usando nossa opção de redirecionamento em nosso arquivo de configuração de autenticação — se você não estiver logado e tentar visitar /my-report
ou report-incident
, você será redirecionado para /login
.
Se você for para /report-incidents
, isso é o que você deve ver.

Esta página é para adicionar incidentes, mas neste momento o formulário não envia incidentes para o nosso servidor porque não estamos fazendo a chamada para o servidor quando o usuário tenta enviar o formulário. Para resolver isso, adicionaremos um método reportIncident
que será chamado quando o usuário clicar em Report . Teremos isso na seção de script do componente. Este método enviará os dados do formulário para o servidor. Atualize seu arquivo report-incident.vue
com o seguinte:
<template> <section class="report"> <h1 class="report__heading">Report an Incident</h1> <form class="report__form"> <div class="input__container"> <label for="title" class="input__label">Title</label> <input type="text" name="title" v-model="incident.title" class="input__field" required /> </div> <div class="input__container"> <label for="location" class="input__label">Location</label> <input type="text" name="location" v-model="incident.location" required class="input__field" /> </div> <div class="input__container"> <label for="comment" class="input__label">Comment</label> <textarea name="comment" v-model="incident.comment" class="input__area" cols="30" rows="10" required ></textarea> </div> <input type="submit" value="Report" class="input__button" @click.prevent="reportIncident" /> <p class="loading__indicator" v-if="loading">Please wait....</p> </form> </section> </template> <script> export default { name: "report-incident", middleware: "auth", data() { return { loading: false, incident: { type: "red-flag", title: "", location: "", comment: "" } }; }, methods: { async reportIncident() { let data = this.incident; let formData = new FormData(); formData.append("title", data.title); formData.append("type", data.type); formData.append("location", data.location); formData.append("comment", data.comment); this.loading = true; try { let res = await this.$store.dispatch("reportIncident", formData); this.$notify({ group: "success", title: "Success", text: "Incident reported successfully!" }); this.loading = false; this.$router.push("/my-reports"); } catch (error) { this.loading = false; this.$notify({ group: "error", title: "Error!", text: error.response ? error.response.data.error : "Sorry an error occured, check your internet" }); } } } }; </script> <style> </style>
Aqui, temos um formulário com campos de entrada para título, local e comentário com vinculação de dados bidirecional usando v-model
. Também temos um botão de submit
com um evento de clique. Na seção de script, temos um método reportIncident
que coleta todas as informações fornecidas no formulário e é enviada ao nosso servidor usando FormData, pois a API foi projetada para aceitar também imagens e vídeos.
Este formData
é anexado a uma ação Vuex usando o método dispatch, se a solicitação for bem-sucedida, você será redirecionado para /my-reports
com uma notificação informando que essa solicitação foi bem-sucedida, caso contrário, você será notificado de um erro com a mensagem de erro .
Neste ponto, ainda não temos a ação reportIncident
em nossa loja, portanto, no console do navegador, você verá um erro se tentar clicar em enviar nesta página.
![mensagem de erro que diz '[Vuex] tipo de ação desconhecido: reportIncident'](/uploads/article/1963/SEKFXM60p8RtNYQ0.png)
Para corrigir isso, adicione a ação reportIncident ao seu arquivo index.js
.
export const actions = { // ... async reportIncident({}, data) { let res = await this.$axios.post('/incident/create', data) return res; } }
Aqui, temos uma função reportIncident
que recebe um objeto de contexto vazio e os dados que estamos enviando de nosso formulário. Esses dados são anexados a uma solicitação de post
que cria um incidente e retorna ao nosso arquivo report-incident.vue
.
Neste ponto, você poderá adicionar um relatório usando o formulário após o qual você será redirecionado para a página /my-reports
.

Esta página deve exibir uma lista de incidentes criados pelo usuário, mas agora mostra apenas o que vemos acima, vamos em frente para corrigir isso.
Vamos usar o método de fetch
que aprendemos para obter esta lista. Atualize seu arquivo my-reports.vue
com o seguinte:
<script> import incidentCard from "@/components/incidentCard.vue"; export default { middleware: "auth", name: "my-reports", data() { return { incidents: [] }; }, components: { incidentCard }, async fetch() { let { data } = await this.$axios.get("/user/incidents"); this.incidents = data.data; } }; </script>
Aqui, usamos o método fetch
para obter incidentes específicos do usuário e atribuir a resposta à nossa matriz de incidentes.
Se você atualizar sua página depois de adicionar um incidente, deverá ver algo assim.

Neste ponto, notamos uma diferença em como o método fetch
e asyncData
carregam nossos dados.
Conclusão
Até agora, aprendemos sobre o módulo Axios e todos os seus recursos. Também aprendemos mais sobre asyncData e como podemos buscar os dois juntos, apesar de suas diferenças. Também aprendemos como realizar a autenticação em nosso aplicativo usando o módulo auth e como usar o middleware de autenticação para proteger nossas rotas. Aqui estão alguns recursos úteis que falam mais sobre tudo o que abordamos.
- Introdução às metatags no Nuxjs.
- Usando o módulo dotenv no Nuxt.
- Usando o Fetch em seu aplicativo Nuxt.
- Introdução ao asyncData.
Recursos
- “Módulo de autenticação”, NuxtJS.org
- “Módulo Axios: Introdução,” NuxtJS.org
-
FormData
, documentos da web MDN - “API: O método
asyncData
,” NuxtJS.org - “A Instância Vue: Diagrama de Ciclo de Vida,” VueJS.org
- “Compreendendo como a
fetch
funciona no Nuxt 2.12,” NuxtJS.org