Skip to content

11. Proyecto [vuejs-09]: uso de un complemento [eventBus]

El proyecto [vuejs-09] es idéntico al proyecto [vuejs-08], salvo que introduce el concepto de complemento. La estructura del proyecto es la siguiente:

Image

11.1. El complemento [./plugins/event-bus]

El script [./event-bus.js] sigue siendo el mismo que en el ejemplo anterior:


import Vue from 'vue';
const eventBus = new Vue();
export default eventBus;

El complemento [./plugins/event-bus.js] es el siguiente:


export default {
  install(Vue, eventBus) {
    // agrega una propiedad [$eventBus] a la clase Vue
    Object.defineProperty(Vue.prototype, '$eventBus', {
      // cuando se hace referencia a Vue.$eventBus, se devuelve el segundo parámetro [eventBus]
      get: () => eventBus,
    })
  }
}

Comentarios

  • Un complemento [Vue] es un objeto que tiene una función [install] (línea 2). Esta función se llamará automáticamente cuando un código declare el uso del complemento;
  • líneas 1-9: el objeto exportado por el script;
  • línea 2: la función [install] acepta aquí dos parámetros:
    • [Vue]: la función obtenida mediante la instrucción [import Vue from ‘Vue’]. Puede asimilarse a una clase;
    • [eventBus]: el objeto exportado por el script [./event-bus];
  • líneas 4-7: modifican la definición (lo que se conoce como el prototipo) de la función [Vue] al agregarle la propiedad [$eventBus]. Si tomamos como ejemplo el término [classe], la propiedad [$eventBus] se agrega a la clase [Vue]. Por lo tanto, los componentes que son instancias de [Vue] tendrán acceso a esta nueva propiedad;
  • la línea 6 indica que, al hacer referencia a la propiedad [Vue].$eventBus, se obtendrá el parámetro [eventBus] de la línea 2. Veremos más adelante que este segundo parámetro será el objeto [eventBus] exportado por el script [./event-bus.js]. Así que, al final, cuando un componente C utilice la expresión [C.$eventBus], hará referencia al objeto [eventBus] exportado por el script [./event-bus.js]. Esto le evitará tener que importar el script [./event-bus.js]. Ahí radica el interés del complemento: simplificar el acceso al objeto [eventBus] exportado por el script [./event-bus.js];
  • Cabe señalar que el complemento no tiene por qué llamarse a sí mismo [event-bus.js]. Se podría haber llamado [plugin-event-bus], por ejemplo;
  • también cabe señalar que el término $ en [$eventBus] es una convención para designar las propiedades de [Vue] que se han agregado mediante complementos. No es obligatorio seguir esta convención. En este texto, la seguiremos;

11.2. El script principal [main.js]

El script [./plugins/event-bus.js] define un complemento para el marco [Vue.js]. Este complemento aún no se utiliza, solo está definido. Es el script [main.js] el que lo activa:


// importaciones
import Vue from 'vue'
import App from './App.vue'

// plugins
import BootstrapVue from 'bootstrap-vue'
Vue.use(BootstrapVue);

// bootstrap
import 'bootstrap/dist/css/bootstrap.css'
import 'bootstrap-vue/dist/bootstrap-vue.css'

// eventbus
import eventBus from './event-bus';
import PluginEventBus from './plugins/event-bus';
Vue.use(PluginEventBus, eventBus);

// configuración
Vue.config.productionTip = false

// instanciación del proyecto [App]
new Vue({
  render: h => h(App),
}).$mount('#app')

Comentarios

  • Las líneas 14 a 16 activan el complemento [PluginEventBus]. Después de la línea 16, todas las instancias de la clase (función) [Vue] tienen la propiedad [$eventBus], que apunta, en cada caso, al mismo objeto exportado por el script [./event-bus.js]. Esto será así para cada uno de los componentes del proyecto;

11.3. La vista principal [App]

La vista principal [App] sigue siendo la misma que en el proyecto anterior.

11.4. El componente [Component1]

El componente [Component1] ahora utiliza su propiedad [$eventBus] para escuchar el evento [someEvent]:


<template>
  <b-row>
    <b-col>
      <b-alert show
               variant="warning"
               v-if="showMsg">Evénement [someEvent] intercepté par [Component1]. Valeur reçue={{data}}</b-alert>
    </b-col>
  </b-row>
</template>

<script>
  export default {
    name: "component1",
    // estado del componente
    data() {
      return {
        data: "",
        showMsg: false
      };
    },
    // métodos de gestión de eventos
    methods: {
      // gestión del evento [someEvent]
      doSomething(data) {
        this.data = data;
        this.showMsg = true;
      }
    },
    // gestión del ciclo de vida del componente
    // evento [created]: se ha creado el componente
    created() {
      // escucha del evento [someEvent]
      this.$eventBus.$on("someEvent", this.doSomething);
    }
  };
</script>

Comentarios

  • línea 33, uso de la propiedad [this.$eventBus] del componente. Además, cabe señalar que el script de la línea 11 ya no importa el script [./event-bus.js];

11.5. El componente [Component2]

El componente [Component2] ahora utiliza su propiedad [$eventBus] para emitir el evento [someEvent]:


<template>
  <div>
    <b-button @click="createEvent">Créer un événement</b-button>
  </div>
</template>
<!-- script -->
<script>
  export default {
    name: "component2",
    // métodos de gestión de eventos
    methods: {
      createEvent() {
        this.$eventBus.$emit("someEvent", { x: 2, y: 4 })
      }
    }
  };
</script>

Comentarios

  • línea 13, uso de la propiedad [this.$eventBus] del componente. Además, cabe señalar que el script de la línea 7 ya no importa el script [./event-bus.js];

11.6. Componente [Component3]

El componente [Component3] tiene el mismo código que [Component1]. Este también escucha el evento [someEvent].

11.7. Ejecución del proyecto

Image

Se obtienen los mismos resultados que en el proyecto anterior.