Comenzando con Axios en Nuxt
En este tutorial, aprenderemos cómo realizar una solicitud en nuestras aplicaciones Nuxt.js usando el módulo Axios. También aprenderemos cómo usar los métodos ayncData
y fetch
para recuperar datos en el lado del servidor usando Axios y las diferencias entre los dos métodos. Finalmente, aprenderemos cómo agregar autenticación a nuestra aplicación usando el módulo Auth.
Nuxt.js proporciona un módulo Axios para una fácil integración con su aplicación. Axios es un cliente HTTP basado en promesas que funciona en el navegador y el entorno Node.js o, en términos más simples, es una herramienta para realizar solicitudes (por ejemplo, llamadas API) en aplicaciones del lado del cliente y el entorno Node.js.
En este tutorial, aprenderemos cómo usar el módulo Axios y cómo realizar una solicitud en el lado del servidor usando asyncData y fetch. Estos dos métodos realizan una solicitud en el lado del servidor, pero tienen algunas diferencias que también cubriremos. Finalmente, aprenderemos cómo realizar autenticación y páginas/rutas seguras utilizando el módulo de autenticación y el middleware de autenticación.
Este artículo requiere conocimientos básicos de Nuxtjs y Vuejs, ya que los desarrollaremos a partir de eso. Para aquellos sin experiencia con Vuejs, les recomiendo comenzar desde su documentación oficial y la página oficial de Nuxt antes de continuar con este artículo.
¿Qué es el módulo Nuxt.js Axios?
Según la documentación oficial ,
"Es una integración segura y sencilla de Axios con Nuxt.js".
Estas son algunas de sus características:
- Establezca automáticamente la URL base para el lado del cliente y el lado del servidor.
- Encabezados de solicitud de proxy en SSR (útil para autenticación).
- Recuperar solicitudes de estilo.
- Integrado con Nuxt.js Progressbar mientras realiza solicitudes.
Para usar el módulo axios en su aplicación, primero deberá instalarlo usando npm
o yarn
.
HILO
yarn add @nuxtjs/axios
MNP
npm install @nuxtjs/axios
Agréguelo a su nuxt.config.js
archivo:
modules: [ '@nuxtjs/axios', ], axios: { // extra config e.g // BaseURL: 'https://link-to-API' }
La modules
matriz acepta una lista de módulos Nuxt.js como dotenv, auth y, en este caso, Axios. Lo que hemos hecho es informar a nuestra aplicación que usaríamos el módulo Axios, al que hacemos referencia usando @nuxtjs/axios
. A esto le sigue la axios
propiedad que es un objeto de configuraciones como baseURL tanto para el lado del cliente como para el servidor.
Ahora puede acceder a Axios desde cualquier lugar de su aplicación llamando this.$axios.method
o this.$axios.$method
. Donde el método puede ser get
, post
o delete
.
Realizar su primera solicitud utilizando Axios
Para este tutorial, he creado una aplicación sencilla en Github . El repositorio contiene dos carpetas, inicio y fin, la carpeta de inicio contiene todo lo que necesita para acceder directamente al tutorial. La carpeta de finalización contiene una versión completa de lo que estaríamos construyendo.
Después de clonar el repositorio y abrir la start
carpeta, necesitaríamos instalar todos nuestros paquetes en el package.json
archivo, así que abra su terminal y ejecute el siguiente comando:
npm install
Una vez hecho esto, podemos iniciar nuestra aplicación usando el npm run dev
comando. Esto es lo que deberías ver cuando vayas a localhost:3000
.
Lo siguiente que tenemos que hacer es crear un .env
archivo en la carpeta raíz de nuestra aplicación y agregarle nuestra URL API. Para este tutorial, usaremos una API de muestra creada para recopilar informes de los usuarios.
API_URL=https://ireporter-endpoint.herokuapp.com/api/v2/
De esta manera, no tenemos que codificar nuestra API en nuestra aplicación, lo cual es útil para trabajar con dos API (desarrollo y producción).
El siguiente paso sería abrir nuestro nuxt.config.js
archivo y agregar la variable ambiental a nuestra configuración de axios que agregamos anteriormente.
/* ** Axios module configuration */ axios: { // See https://github.com/nuxt-community/axios-module#options baseURL: process.env.API_URL, },
Aquí, le decimos a Nuxt.js que use esto baseURL
tanto para nuestras solicitudes del lado del cliente como del lado del servidor siempre que usemos este módulo de Axios.
Ahora, para obtener una lista de informes, abramos el index.vue
archivo y agreguemos el siguiente método a la sección del script.
async getIncidents() { let res = await this.$store.dispatch("getIncidents"); this.incidents = res.data.data.incidents;}
Lo que hemos hecho es crear una función asíncrona a la que llamamos getIncidents()
y podemos saber qué hace por el nombre: obtiene una lista de incidentes utilizando el método de acción de la tienda Vuex this.$store.dispatch
. Asignamos la respuesta de esta acción a nuestra propiedad de incidentes para poder utilizarla en el componente.
Queremos llamar al getIncidents()
método cada vez que se monte el componente. Podemos hacerlo usando el mounted
gancho.
mounted() { this.getIncidents() }
mounted()
es un gancho de ciclo de vida que se llama cuando se monta el componente. Eso hará que la llamada a la API se realice cuando se monte el componente. Ahora, vayamos a nuestro index.js
archivo en nuestra tienda y creemos esta acción desde donde realizaremos nuestra solicitud de Axios.
export const actions = { async getIncidents() { let res = await this.$axios.get('/incidents') return res; }}
Aquí, creamos la acción llamada getIncidents
que es una función asíncrona, luego esperamos una respuesta del servidor y devolvemos esta respuesta. La respuesta de esta acción se envía de vuelta a nuestro getIncidents()
método en nuestro index.vue
archivo.
Si actualizamos nuestra aplicación, ahora deberíamos poder ver una larga lista de incidentes representados en la página.
Hicimos nuestra primera solicitud usando Axios pero no nos detendremos ahí, vamos a probar asyncData
y fetch
ver las diferencias entre ellos y el uso de Axios.
Datos asíncronos
AsyncData recupera datos en el lado del servidor y se llama antes de cargar el componente de la página. No tiene acceso this
porque se llama antes de que se creen los datos del componente de la página. this
solo está disponible después de que created
se ha llamado al enlace, por lo que Nuxt.js fusiona automáticamente los datos devueltos con los datos del componente.
Su uso asyncData
es bueno para SEO porque recupera el contenido de su sitio en el lado del servidor y también ayuda a cargar contenido más rápido. Tenga en cuenta que el asyncData
método solo se puede utilizar en la carpeta de páginas de su aplicación, ya que no funcionaría en la carpeta de componentes. Esto se debe a asyncData
que se llama al gancho antes de que se cree el componente.
Agreguemos asyncData
a nuestro index.vue
archivo y observemos qué tan rápido se cargan nuestros datos de incidentes . Agregue el siguiente código después de nuestra propiedad de componentes y permítanos deshacernos de nuestro gancho montado.
async asyncData({ $axios }) { let { data } = await $axios.get("/incidents"); return { incidents: data.data.incidents }; }, // mounted() { // this.getIncidents(); // },
Aquí, el asyncData
método acepta una propiedad del contexto $axios
. Usamos esta propiedad para obtener la lista de incidentes y luego se devuelve el valor. Este valor se inyecta automáticamente en nuestro componente. Ahora, puedes notar qué tan rápido se carga tu contenido si actualizas la página y en ningún momento hay ningún incidente que renderizar.
Buscar
El método Fetch también se utiliza para realizar solicitudes en el lado del servidor. Se llama después del enlace creado en el ciclo de vida, lo que significa que tiene acceso a los datos del componente. A diferencia del asyncData
método, el método de recuperación se puede utilizar en todos los archivos .vue y con la tienda Vuex. Esto significa que si tiene lo siguiente en su función de datos.
data() { return { incidents: [], id: 5, gender: 'male' };}
Puede modificar fácilmente la identificación o el género llamando this.id
a o this.gender
.
Usando Axios como complemento
Durante el proceso de desarrollo con Axios, es posible que necesite configuración adicional, como crear instancias e interceptores para su solicitud, para que su aplicación pueda funcionar según lo previsto y, afortunadamente, podemos hacerlo extendiendo nuestro Axios a un complemento.
Para ampliar axios
, debe crear un complemento (por ejemplo, axios.js ) en su plugins
carpeta.
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 es un ejemplo de un complemento que escribí para una aplicación Nuxt. Aquí, su función toma un objeto de contexto de y que $axios
usaríamos para configurar el complemento. Lo primero que hacemos es escuchar un error con estado de uso y redirigir al usuario a la página de inicio de sesión.store
redirect
500
$axios.onError
También tenemos un interceptor que intercepta cada solicitud de respuesta que hacemos en nuestra aplicación y verifica si el estado de la respuesta que obtenemos es 200
. Si eso es cierto procedemos y verificamos que haya un response.request.responseURL
y si incluye inicio de sesión. Si esto resulta ser cierto, enviamos esta respuesta utilizando el método de envío de nuestra tienda, donde luego mutó en nuestro estado.
Agregue este complemento a su nuxt.config.js
archivo:
plugins: [ '~/plugins/axios' ]
Después de hacer esto, su complemento Axios interceptará cualquier solicitud que realice y verificará si ha definido un caso especial para ella.
Introducción al módulo de autenticación
El módulo de autenticación se utiliza para realizar la autenticación de su aplicación Nuxt y se puede acceder a él desde cualquier lugar de su aplicación usando $this.auth
. También está disponible en fetch
, y desde el objeto asyncData
de contexto como .middleware
NuxtInitServer
$auth
Proporciona context
objetos/parámetros adicionales de los componentes de Nuxt a Vue y está disponible en áreas especiales del ciclo de vida de Nuxt como las mencionadas anteriormente.
Para usar el módulo de autenticación en su aplicación, deberá instalarlo usando yarn
o npm
.
HILO
yarn add @nuxtjs/auth
MNP
npm install @nuxtjs/auth
Agréguelo a su nuxt.config.js
archivo.
modules: [ '@nuxtjs/auth'],auth: { // Options}
La propiedad de autenticación acepta una lista de propiedades como strategies
y redirect
. Aquí, strategies
acepta su método de autenticación preferido que puede ser:
local
Para flujo basado en nombre de usuario/correo electrónico y contraseña.facebook
Para utilizar cuentas de Facebook como medio de autenticación.Github
Para autenticar usuarios con cuentas de Github.Google
Para autenticar usuarios con cuentas de Google.- Autenticación0
- Pasaporte Laravel
La propiedad de redirección acepta un objeto de enlaces para:
login
Los usuarios serán redirigidos a este enlace si es necesario iniciar sesión.logout
Los usuarios serán redirigidos aquí si, después de cerrar sesión, la ruta actual está protegida.home
Los usuarios serán redirigidos aquí después de iniciar sesión.
Ahora, agreguemos lo siguiente a nuestro nuxt.config.js
archivo.
/* ** 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 }, },}
Tenga en cuenta que el auth
método funciona mejor cuando se user
proporciona un punto final en la opción anterior.
Dentro del auth
objeto de configuración, tenemos una redirect
opción en la que configuramos nuestra ruta de inicio de sesión/login
, la ruta de cierre de sesión/
y la ruta de inicio/my-reports
, las cuales se comportarán como se esperaba. También tenemos una tokenType
propiedad que representa el tipo de Autorización en el encabezado de nuestra solicitud de Axios. Está configurado Bearer
de forma predeterminada y se puede cambiar para que funcione con su API.
Para nuestra API, no existe ningún tipo de token y es por eso que lo dejaremos como una cadena vacía. Representa tokenName
el nombre de la autorización (o la propiedad del encabezado a la que desea adjuntar su token) dentro del encabezado en su solicitud de Axios.
De forma predeterminada, está configurado en Authorization
pero para nuestra API, el nombre de autorización es x-auth
. La autoFetchUser
propiedad se utiliza para permitir que el usuario obtenga objetos utilizando la user
propiedad del punto final después de iniciar sesión. Es true
de forma predeterminada, pero nuestra API no tiene un user
punto final, por lo que lo configuramos en false
.
Para este tutorial, usaríamos la estrategia local. En nuestras estrategias, tenemos la opción local con puntos finales para inicio de sesión, usuario y cierre de sesión, pero en nuestro caso, solo usaríamos la *login*
opción porque nuestra API de demostración no tiene un *logout*
punto final y nuestro objeto de usuario se devuelve cuando *login*
tiene éxito.
Nota: El auth
módulo no tiene una opción de registro de punto final, lo que significa que vamos a registrarnos de la manera tradicional y redirigir al usuario a la página de inicio de sesión donde realizaremos la autenticación usando this.$auth.loginWith
. Este es el método utilizado para autenticar a sus usuarios. Acepta una 'estrategia' (p. ej. local
) como primer argumento y luego un objeto para realizar esta autenticación. Eche un vistazo al siguiente ejemplo.
let data { email: 'test@test.com', password: '123456'}this.$auth.loginWith('local', { data })
Usando el módulo de autenticación
Ahora que hemos configurado nuestro módulo de autenticación, podemos proceder a nuestra página de registro. Si visita la /register
página, debería ver un formulario de registro.
Hagamos que este formulario sea funcional agregando el siguiente 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" }); } }}
Aquí, tenemos una función asíncronaregisterUser
llamada que está vinculada a un evento de clic en nuestra plantilla y realiza una solicitud de Axios envuelta en un bloque try/catch a un punto final /user/create
. Esto redirige a la /login
página y notifica al usuario sobre un registro exitoso. También contamos con un bloque catch que alerta al usuario de cualquier error si la solicitud no tiene éxito.
Si el registro se realiza correctamente, será redirigido a la página de inicio de sesión.
Aquí, usaremos el método de autenticación this.$auth.loginWith('local', loginData)
y luego usaremos this.$auth.setUser(userObj)
para configurar el usuario en nuestra auth
instancia.
Para que la página de inicio de sesión funcione, agreguemos el siguiente código a nuestro login.vue
archivo.
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" }); } }}
Creamos una función asíncrona llamada logIn
usando el método de autenticación this.$auth.loginWith('local, loginData)
. Si este intento de inicio de sesión tiene éxito, asignamos los datos del usuario a nuestra instancia de autenticación this.$auth.setUser(userInfo)
y redirigimos al usuario a la /my-report
página.
Ahora puede obtener datos de usuario usando this.$auth.user
o usando Vuex, this.$store.state.auth.user
pero eso no es todo. La auth
instancia contiene algunas otras propiedades que puede ver si inicia sesión o verifica su estado usando las herramientas de desarrollo de Vue.
Si inicia sesión this.$store.state.auth
en la consola, verá esto:
{ "auth": { "user": { "id": "d7a5efdf-0c29-48aa-9255-be818301d602", "email": "tmxo@test.com", "lastName": "Xo", "firstName": "Tm", "othernames": null, "isAdmin": false, "phoneNumber": null, "username": null }, "loggedIn": true, "strategy": "local", "busy": false }}
La auth
instancia contiene una loggedIn
propiedad que es útil para cambiar entre enlaces autenticados en la sección de navegación/encabezado de su aplicación. También contiene un método de estrategia que indica el tipo de estrategia que ejecuta la instancia (por ejemplo, local).
Ahora, haremos uso de esta loggedIn
propiedad para organizar nuestros nav
enlaces. Actualice su navBar
componente a lo siguiente:
template header div nuxt-link to="/" Logo / /nuxt-link /div nav div v-if="auth.loggedIn" p{{ auth.user.email }}/p button nuxt-link to="/report-incident"Report incident/nuxt-link /button button nuxt-link to="/my-reports"My Reports/nuxt-link /button button @click.prevent="logOut"Log out/button /div button v-if="!auth.loggedIn" nuxt-link to="/login"Login/nuxt-link /button button v-if="!auth.loggedIn" nuxt-link to="/register"Register/nuxt-link /button /nav /header/templatescriptimport { 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 }};/scriptstyle/style
En nuestra sección de plantilla, tenemos varios enlaces a diferentes partes de la aplicación que estamos usando ahora auth.loggedIn
para mostrar los enlaces apropiados según el estado de autenticación. Tenemos un botón de cierre de sesión que tiene un click
evento con una logOut()
función adjunta. También mostramos el correo electrónico del usuario obtenido de la propiedad de autenticación a la que se accede desde nuestra tienda Vuex utilizando el mapState
método que asigna nuestra autenticación de estado a la propiedad calculada del componente de navegación. También tenemos un logout
método que llama a nuestra acción Vuex logOut
y redirige al usuario a la login
página.
Ahora, sigamos adelante y actualicemos nuestra tienda para tener una logOut
acción.
export const actions = { // .... logOut() { this.$auth.logout(); }}
La logOut
acción llama al logout
método de autenticación que borra los datos del usuario, elimina los tokens localStorage
y los establece loggedIn
en false
.
Las rutas como /my-reports
y report-incident
no deberían ser visibles para los huéspedes , pero en este punto de nuestra aplicación, ese no es el caso. Nuxt no tiene un protector de navegación que pueda proteger sus rutas, pero sí tiene el middleware de autenticación . Le brinda la libertad de crear su propio middleware para que pueda configurarlo para que funcione de la manera que desee.
Se puede configurar de dos maneras:
- Por ruta.
- Globalmente para toda la aplicación en su
nuxt.config.js
archivo.
router: { middleware: ['auth']}
Este auth
middleware funciona con su auth
instancia, por lo que no necesita crear un auth.js
archivo en su carpeta de middleware.
Agreguemos ahora este middleware a nuestros archivos my-reports.vue
y report-incident.vue
. Agregue las siguientes líneas de código a la sección de secuencia de comandos de cada archivo.
middleware: 'auth'
Ahora, nuestra aplicación verificaría si el usuario que intenta acceder a estas rutas tiene un auth.loggedIn
valor de true
. Los redireccionará a la página de inicio de sesión usando nuestra opción de redireccionamiento en nuestro archivo de configuración de autenticación ; si no ha iniciado sesión e intenta visitar /my-report
o report-incident
, será redirigido a /login
.
Si vas a /report-incidents
, esto es lo que deberías ver.
Esta página es para agregar incidentes, pero en este momento el formulario no envía incidentes a nuestro servidor porque no estamos realizando la llamada al servidor cuando el usuario intenta enviar el formulario. Para resolver esto, agregaremos un reportIncident
método que se llamará cuando el usuario haga clic en Informe . Tendremos esto en la sección de script del componente. Este método enviará los datos del formulario al servidor. Actualice su report-incident.vue
archivo con lo siguiente:
template section h1Report an Incident/h1 form div label for="title"Title/label input type="text" name="title" v-model="incident.title" required / /div div label for="location"Location/label input type="text" name="location" v-model="incident.location" required / /div div label for="comment"Comment/label textarea name="comment" v-model="incident.comment" cols="30" rows="10" required /textarea /div input type="submit" value="Report" @click.prevent="reportIncident" / p v-if="loading"Please wait..../p /form /section/templatescriptexport 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" }); } } }};/scriptstyle/style
Aquí tenemos un formulario con campos de entrada para título, ubicación y comentario con enlace de datos bidireccional usando v-model
. También tenemos un submit
botón con un evento de clic. En la sección de script, tenemos un reportIncident
método que recopila toda la información proporcionada en el formulario y se envía a nuestro servidor usando FormData porque la API está diseñada para aceptar también imágenes y videos.
Esto formData
se adjunta a una acción de Vuex utilizando el método de envío; si la solicitud se realiza correctamente, se le redirigirá con /my-reports
una notificación que le informará que esta solicitud se realizó correctamente; de lo contrario, se le notificará un error con el mensaje de error.
En este punto, todavía no tenemos reportIncident
acción en nuestra tienda, por lo que en la consola de su navegador verá un error si intenta hacer clic en enviar en esta página.
Para solucionar este problema, agregue la acción reportIncidentindex.js
a su archivo.
export const actions = { // ... async reportIncident({}, data) { let res = await this.$axios.post('/incident/create', data) return res; }}
Aquí tenemos una reportIncident
función que toma un objeto de contexto vacío y los datos que enviamos desde nuestro formulario. Luego, estos datos se adjuntan a una post
solicitud que crea un incidente y regresa a nuestro report-incident.vue
archivo.
En este punto, debería poder agregar un informe utilizando el formulario, después del cual será redirigido a /my-reports
la página.
Esta página debería mostrar una lista de incidentes creados por el usuario, pero en este momento solo muestra lo que vemos arriba, sigamos adelante para solucionarlo.
Usaremos el fetch
método que aprendimos para obtener esta lista. Actualice su my-reports.vue
archivo con lo siguiente:
scriptimport incidentCard from "@/components/incidentCard.vue";export default { middleware: "auth", name: "my-reports", data() { return { incidents: [] }; }, components: { incidentCard }, async fetch() { let { data } = await this.$axios.g
Deja un comentario