Mixins Vue: compartir lógica entre componentes

Clase 37 de 53Curso Profesional de Vue.js 2

Resumen

Los mixins en Vue.js permiten reutilizar lógica entre componentes sin duplicar código. Aquí verás cómo crear un trackMixin, mover el método selectTrack y aplicarlo en los componentes de Platzi Music: track y trackDetail, manteniendo el comportamiento, los eventos y la claridad de la vista.

¿Qué son los mixins en Vue.js y por qué convienen?

Los mixins aplican una especie de herencia por combinación: en lugar de sobrescribir, Vue hace un merge de las opciones del mixin con las del componente. Así, puedes compartir data, computed, methods, watchers y directives del viewModel sin perder cambios. En cambio, el HTML no se mezcla con mixins: para eso están los componentes.

  • Reutilización de funcionalidad entre múltiples componentes sin copiar y pegar.
  • Merge automático de opciones: no se pisan, se combinan.
  • Múltiples mixins por componente: útil para lógicas transversales como una propiedad isLoading.
  • Plantillas aparte: el mixin comparte lógica, no estructura de HTML.

¿Cómo crear y exportar un mixin para tracks?

Se organiza el proyecto creando la carpeta mixins dentro de source y el archivo track.js. Allí se define el objeto trackMixin con la lógica compartida y se exporta.

¿Qué estructura mínima debe tener el mixin?

  • Archivo: source/mixins/track.js.
  • Objeto: trackMixin con las opciones del viewModel que quieras compartir.
  • Exportación con export default para importarlo luego en los componentes.
// source/mixins/track.js
const trackMixin = {
  methods: {
    selectTrack () {
      // lógica existente para seleccionar y emitir el track.
      // se copió desde el componente original.
    }
  }
}

export default trackMixin

¿Qué lógica compartir entre track y trackDetail?

Se identificó que ambos necesitan el método selectTrack para seleccionar una canción y emitir eventos al reproductor. Esa lógica se mueve al mixin para no mantenerla en dos lugares.

  • Se copia selectTrack desde el componente track.
  • Se elimina del componente y se centraliza en el mixin.
  • Luego se inyecta en cada componente con la propiedad mixins.

¿Cómo mejorar la vista de trackDetail sin duplicar HTML?

Se crea una vista propia en trackDetail sin el componente pmTrack, usando clases de Bulma como is-3, is-8, text-center, panel y media object. El HTML queda en el componente, mientras la lógica se delega al mixin.

  • Imagen del álbum con la primera portada:
<img :src="track.album.images[0].url" alt="Portada del álbum" />
  • Botón de reproducción con evento click ligado a selectTrack:
<button class="button is-primary is-large" @click="selectTrack">Play</button>
  • Lista dinámica de propiedades del objeto track usando la directiva de iteración v-for con objeto: claves y valores.
<ul>
  <li v-for="(value, key) in track" :key="key">
    <strong>{{ key }}</strong>: <span>{{ value }}</span>
  </li>
</ul>

Nota: los mixins no comparten HTML, solo lógica; la plantilla se construye en cada componente.

¿Cómo implementar el mixin en track y trackDetail?

La integración es directa: se importa el mixin y se registra con la propiedad mixins. Así el componente accede a selectTrack sin duplicar código.

¿Cómo importar e inyectar el mixin?

  • Importación con import usando el alias definido.
  • Registro en el arreglo mixins del componente.
// dentro de track.vue o trackDetail.vue
import trackMixin from '@mixins/track'

export default {
  mixins: [trackMixin],
  // props, data, created, etc., propios del componente.
}

¿Qué validar después de mover la lógica?

  • En track: probar la búsqueda y el botón de play para confirmar que selectTrack sigue emitiendo y el reproductor responde.
  • En trackDetail: verificar que el botón activa la misma lógica compartida y que la UI nueva con Bulma se renderiza correctamente.
  • En herramientas de desarrollo de Vue: comprobar que el componente mantiene su estado y eventos.

¿Qué ventajas obtienes al refactorizar con mixins?

  • Menos duplicación y mantenimiento más simple: cambias en un solo lugar.
  • Consistencia en la emisión de eventos entre vistas.
  • Posibilidad de agregar otros mixins para estados transversales como isLoading sin mezclar responsabilidades.

¿Te gustaría comentar qué otra lógica moverías a un mixin en tu proyecto Vue o qué patrón reutilizas para mantener tus componentes limpios?