Programación usando VueJS (Comunicación entre componentes). Parte 6

Comunicación entre componentes (Padre e hijo)

Para continuar con el curso de VueJS y avanzar nuestra aplicación, ahora aprenderemos a comunicar los componentes entre si.

En esta parte vamos a ver como realizar la comunicación entre un componente padre a un componente hijo y de un componente hijo a un componente padre.

Si la comunicación se realiza desde el padre hacia el hijo usaremos las propiedades, pero si la comunicación es desde el hijo hacia el padre usaremos los eventos.

Sabiendo como se realiza la comunicación entre padres e hijos, ahora vamos a poner en practica este mecanismo.

Vamos abrir el fichero filmCard.vue de nuestro proyecto:

Ahora mismo existe una comunicación desde el padre App.vue hacia el hijo filmCard.vue usando las propiedades

Desde el padre le estamos pasando la respuesta del API usando la propiedad data-film.

Comunicación desde el hijo hacia el padre

Bien, ahora añadiremos un ejemplo realizando la comunicación desde el hijo hacia el padre usando eventos.

Usaremos el fichero filmCard.vue y añadiremos el código necesario para lanzar un evento.

Como puedes comprobar en el código anterior, hemos creado un método que se encarga de emitir un evento hacia el padre usando la función $emit.

Ahora volveremos al fichero App.vue para añadir la capacidad de escuchar ese evento.

Para esa función usaremos la directiva v-on (@) que junto al nombre del evento que añadimos en el hijo, permitirá crear la comunicación.

A continuación el código nuevo de App.vue:

En el nuevo código notaras algunos cambios como un iframe para cargar la búsqueda en la wikipedia, métodos, computed properties y sobre todo el encargado de escuchar el evento entre el hijo y el padre, @search-in-wikipedia.

Slots en Vue

Pero…, ¿no estábamos hablando de comunicación entre componentes?.

Bien, los slots nos permiten inyectar html desde el componente padre al componente hijo.

En la versión 2 de Vue podemos crear los slots con datos que son pasados a través de los atributos del componente y así hacerlos más dinámicos.

Para usar los slot en Vue, vamos a usar el componente que tiene Vue llamado slot.

El componente slot que ofrece Vue se puede usar sin nombre o añadiendo la propiedad name asignado un nombre a ese slot.

App.vue

filmCard.vue

En el código anterior podemos comprobar el uso de slot, defiendo en el padre los siguientes slots:

Cuando usamos el componente slot sin el atributo name, usara por defecto en el hijo el slot que encuentre.

De hecho en este ejemplo que tiene el componente slot sin nombre, el contenido h3 h5 se inyectara en el slot sin nombre.

Slots en funcionamiento

A continuación un vídeo probando los slots, donde comprobaremos como funcionan los slots y los fallos que se pueden mostrar en la consola.

En el vídeo anterior podemos comprobar que cuando usamos el componente slot por defecto o con el mismo nombre mas de una vez, el navegador nos informa de que existen duplicados.

Como hemos podido comprobar el uso de slot en Vue abre un mundo de posibilidades a la personalización de nuestros componentes, ya que con un solo componente podemos cambiar el contenido por completo y adaptarlo a nuestras necesidades.

De hecho, el uso mas común de los slot suele ser para crear ventanas modales, ventanas emergentes, listados, etc.., donde realmente el contenedor es el mismo pero queremos cambiar el contenido.

Comunicación con cualquier componente (sin vinculo)

Como hemos podido comprobar, la comunicación entre padres e hijos en Vue es fácil, pero…¿que ocurre cuando no existe ningún vínculo?.

Vue no tiene ningún mecanismo directo para comunicar entre componentes que no tengan un vinculo, pero si nos ofrece una alternativa mediante Plugins Event Bus.

Bien, ¿y que es un plugin?. Lo podemos definir como una funcionalidad que permite extender el comportamiento de la instancia de Vue.

Para crear un plugin, mi recomendación es crear una carpeta llamada plugin, donde añadiremos los plugin.

eventBus.js

Con el código anterior acabamos de crear la estructura básica de un plugin para Vue, que en nuestro ejemplo se encargara de la gestión de los eventos.

Realmente no tiene mucha complicación el código anterior, pero me gustaría remarcar dos cosas interesantes:

  • Cuando creamos un plugin en Vue.js tenemos que usar el método install, ya que este recibirá como parámetro la instancia de Vue.
  • Usaremos el prototype en Vue para extender y añadir comportamientos, que junto al objeto $bus ($ para saber que es un plugin y diferenciar de las propiedades y/o métodos del modelo) declararemos una nueva instancia de Vue, aprovechando las funcionalidades que ofrece Vue.

Usando el event bus

Con nuestra base del plugin creado y el event bus declarado, vamos a usarlo en nuestra aplicación.

Vamos a ir hasta el fichero main.js y lo vamos a importar y usar desde allí.

Ahora para usar el event bus, vamos a definir en nuestra aplicación todos los sitios donde necesitamos hacer $emit y $on para que funcione.

A continuación los ficheros modificados y funcionando correctamente usando el event bus:

App.vue

filmCard.vue

filmCardDetail.vue

Como hemos podido comprobar, esta forma de comunicar los componentes nos permite ir un paso mas allá en la comunicación entre componentes.

Aunque es una buena forma para comunicar los componentes no es la forma mas recomendable si el proyecto empieza a crecer, ya que el mantenimiento usando el event bus acabaría demandando mucho tiempo, y para un mantenimiento mas controlado usaremos Vuex ( es una implementación de Flux, que es un patrón de diseño para controlar el estado de nuestras aplicaciones).

Para finalizar un vídeo con aplicación funcionando: