Instalación de Viewex en Platzi Music

Clase 44 de 53Curso Profesional de Vue.js 2

Resumen

Integrar un state management sólido marca la diferencia en la experiencia de usuario. Aquí verás cómo se implementa Viewex en Platzi Music, cómo reemplazar el event bus por un store centralizado y cómo optimizar llamadas a la API con actions, mutations y getters, además del uso del spread operator para mapState, mapActions y mapGetters.

¿Cómo instalar Viewex y configurar Bubble para usar spread operator?

Para iniciar, se instalan las dependencias y se configura el preset necesario para habilitar el spread operator.

  • Instalar Viewex con NPM.
npm i -S viewex
  • Instalar el preset de Bubble para spread operator.
npm i -D bubble-preset-stage-2
  • Agregar el preset en el archivo Bubble RC en la línea posterior a environment. Combina presets si ya existe otro.
  • Cada cambio en webpack o Bubble requiere detener y relanzar el proceso de desarrollo.
npm run dev

Esta base habilita el uso de mapState, mapActions y mapGetters con el spread operator y prepara el proyecto para el store centralizado.

¿Cómo crear el store y reemplazar el event bus?

El objetivo es centralizar el flujo de datos y evitar la complejidad de comunicar componentes por props y eventos.

  • Crear el archivo store.js dentro de source.
  • Registrar el plugin y crear la instancia del store.
import Vue from 'vue'
import Viewex from 'viewex'

Vue.use(Viewex)

export const store = new Viewex.Store({
  state: {
    track: {}
  },
  mutations: {
    setTrack(state, track) {
      state.track = track
    }
  }
})
  • Importar el store en main.js e inyectarlo en la instancia de Vue junto al router.

Con esto, se elimina el event bus y se usa this.$store.commit('setTrack', track) para actualizar el estado. Las mutations permiten rastrear cambios, depurar y volver a estados previos.

¿Cómo vincular el player con mapState y computed?

El Player Component deja de manejar data local y escucha el estado global.

  • Importar mapState desde Viewex.
  • Usar computed con mapState y el spread operator para enlazar track.
import { mapState } from 'viewex'

export default {
  computed: {
    ...mapState(['track'])
  }
}

El binding se actualiza automáticamente cuando cambia el store.

¿Qué ventajas concretas tiene centralizar el estado?

  • Menos acoplamiento entre componentes.
  • Flujo de datos claro y mantenible.
  • Trazabilidad de cambios con commits.
  • Posibilidad de optimizar llamadas a la API.

¿Cómo optimizar Track Detail con actions y mapActions?

Se crea una action para obtener la canción por ID y se reutiliza la data ya existente para evitar solicitudes innecesarias.

¿Cómo se define la action getTrackByID?

  • Las actions manejan código asincrónico y, al resolver, comitean una mutation.
import trackService from '@/services/track'

const actions = {
  getTrackByID(context, payload) {
    return trackService.getByID(payload.id)
      .then(response => {
        context.commit('setTrack', response)
        return response
      })
  }
}
  • Flujo recomendado: la action obtiene la respuesta, hace commit a la mutation y esta actualiza el state.

¿Cómo decidir entre usar el store o llamar a la API?

En Track Detail se combinan mapState y mapActions. Si vienes desde search, el track ya está en memoria. Si recargas la página o entras directo por URL, se llama a la API.

import { mapState, mapActions } from 'viewex'

export default {
  computed: {
    ...mapState(['track'])
  },
  methods: {
    ...mapActions(['getTrackByID'])
  },
  created() {
    const id = this.$route.params.id
    const noTrack = !this.track || !this.track.id
    const different = this.track && this.track.id !== id

    if (noTrack || different) {
      this.getTrackByID({ id }).then(() => {
        console.log('track loaded')
      })
    }
  }
}

Resultado: navegación inmediata cuando la data ya existe en el store y solicitud a la API solo cuando es necesario. Se evita latencia y carga duplicada.

¿Cómo prevenir errores por objetos vacíos en la vista?

  • Controlar render con v-if hasta tener track.id para no acceder a propiedades inexistentes.
<div v-if="track && track.id">
  <!-- contenido que usa track -->
</div>
  • Manejar estados iniciales vacíos antes de acceder a estructuras anidadas.

¿Cómo crear un getter útil y usarlo en la interfaz?

Un getter permite derivar datos del estado sin duplicarlos. Ejemplo: mostrar título con artista.

const getters = {
  trackTitle(state) {
    if (!state.track.name) return ''
    return `${state.track.name} - ${state.track.artist[0].name}`
  }
}

Usarlo en Track Detail con mapGetters y computed.

import { mapState, mapActions, mapGetters } from 'viewex'

export default {
  computed: {
    ...mapState(['track']),
    ...mapGetters(['trackTitle'])
  }
}

Ventajas del getter: - Lógica de presentación centralizada. - Recalcula de forma reactiva cuando cambia el estado. - Evita errores cuando el objeto aún no existe.

¿Qué más considerar a escala?

  • Viewex soporta módulos para dividir el store por dominio como track, users o albums, y luego centralizarlos. Útil en aplicaciones grandes.
  • Se mencionan conceptos clave: estado centralizado, patrón de flags, mutations, actions, getters y computed trabajando juntos para un flujo consistente entre componentes.

¿Tienes dudas o quieres compartir cómo aplicaste estas ideas en tu proyecto? Escribe tus preguntas o comentarios y conversemos.