Proyecto cliente SPA para la API de películas con Nuxt.js

Creando nuestro store

Un store es como un almacén de datos transversal accesible desde cualquier parte de nuestra aplicación. Nuxt implementa el store Vuex en su núcleo, por lo que es relativamente fácil empezar a trabajar, sólo tenemos que crear el fichero index.js dentro del directorio store/.

Sin embargo hay dos cosas a tener en cuenta sobre Vuex:

  • Los estados (o datos del store, por decirlo de alguna forma) son reactivos, de manera que si se modifica, el cambio se reflejará instantáneamente en toda la aplicación.

  • El segundo es que no se puede mutar un estado directamente, es necesario hacer lo que denomina un “commit”. Esto asegura que los cambios dejan un rastro, lo que nos permite entender mejor nuestras aplicaciones.

Hay dos estados que vamos a manejar en nuestra aplicación, el primero es el token y el segundo un "nombre" de usuario. En realidad no será el nombre, simplemente extraemos la primera parte del email.

Para añadir nuestros los dos estados lo haremos así:

store/index.js

export const state = () => ({
  token: null,
  user: null
})

Justo debajo necesitamos crear un par de mutaciones para establecer sus valores:

export const mutations = {
  saveUser(state, user){
    state.user = user;
  },
  saveToken(state, token){
    state.token = token;
  }
}

Una vez lo tengamos podemos empezar a trabajar con nuestro Store.

Justo en el momento del login almacenaremos los valores si recibimos correctamente el token de la API, también esconderemos la ventana modal del formulario de login:

layouts/default.vue

login() {
  return this.$axios.post('/auth/login/', {
    email: this.loginEmail,
    password: this.loginPassword
  })
  .then((res) => {
    if (res.data.key){
      this.$store.commit('saveToken', res.data.key)
      this.$store.commit('saveUser', this.loginEmail.split("@")[0])
      // Reiniciamos los campos
      this.loginEmail = ''
      this.loginPassword = ''
      // Escondemos la modal
      this.isLoginActive = false;
    }
  })
  .catch((error) => {
    alert(Object.values(error.response.data))
  })
},

Con esto deberíamos ser capaces de identificarnos al hacer login, el problema es que no podemos saber si realmente estamos identificados o no. Bueno, sí que podemos, debugeando el valor de nuestros estados en medio del código o usando la extensión Vue Devtools de Chrome, bastante recomendable para estos casos.

Una forma interesante de acceder a los estados es usar un valor computado, esto evita algunos errores sobretodo usando apps universales con SSR.

computed: {
  user: function () {
    return this.$store.state.user;
  }
},

Con esto podemos consultar el nombre del usuario autenticado en todo momento y alternar algunas opciones en el menú superior:

<a class="button" v-if="!user">
  <strong>Registro</strong>
</a>
<a class="button is-primary" v-else>
  Bienvenido {{user}} 😄
</a>
<a class="button is-light" @click="isLoginActive=true" v-if="!user">
  Acceder
</a>
<a class="button is-light" @click="logout" v-else>
  Salir
</a>

Ya sólo nos faltaría crear el método para hacer el Logout, cuyo propósito sería simplemente establecer los estados a null:

logout() {
  this.$store.commit('saveToken', null)
  this.$store.commit('saveUser', null)
}