Skip to content

11. Projekt [vuejs-09]: wykorzystanie wtyczki [eventBus]

Projekt [vuejs-09] jest identyczny z projektem [vuejs-08], z tą różnicą, że wprowadza pojęcie wtyczki. Struktura katalogów projektu wygląda następująco:

Image

11.1. Wtyczka [./plugins/event-bus]

Skrypt [./event-bus.js] pozostaje taki sam jak w poprzednim przykładzie:


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

Wtyczka [./plugins/event-bus.js] wygląda następująco:


export default {
  install(Vue, eventBus) {
    // dodaje właściwość [$eventBus] do klasy Vue
    Object.defineProperty(Vue.prototype, '$eventBus', {
      // gdy odwołuje się do Vue.$eventBus, zwracany jest drugi parametr [eventBus]
      get: () => eventBus,
    })
  }
}

Komentarze

  • Wtyczka [Vue] jest obiektem posiadającym funkcję [install] (wiersz 2). Funkcja ta zostanie automatycznie wywołana, gdy kod zadeklaruje użycie wtyczki;
  • wiersze 1–9: obiekt eksportowany przez skrypt;
  • wiersz 2: funkcja [install] przyjmuje tutaj dwa parametry:
    • [Vue]: funkcja uzyskana za pomocą instrukcji [import Vue from ‘Vue’]. Można ją traktować jako klasę;
    • [eventBus]: obiekt eksportowany przez skrypt [./event-bus];
  • wiersze 4–7: modyfikują definicję (zwaną prototypem) funkcji [Vue] poprzez dodanie do niej właściwości [$eventBus]. Jeśli weźmiemy pod uwagę termin [classe], właściwość [$eventBus] zostaje dodana do klasy [Vue]. Komponenty będące instancjami klasy [Vue] będą zatem miały dostęp do tej nowej właściwości;
  • wiersz 6 wskazuje, że przy odwołaniu się do właściwości [Vue].$eventBus otrzymamy parametr [eventBus] z wiersza 2. Nieco dalej zobaczymy, że tym drugim parametrem będzie obiekt [eventBus] wyeksportowany przez skrypt [./event-bus.js]. W rezultacie, gdy komponent C użyje wyrażenia [C.$eventBus], będzie on odwoływał się do obiektu [eventBus] wyeksportowanego przez skrypt [./event-bus.js]. Dzięki temu nie będzie musiał importować skryptu [./event-bus.js]. Na tym polega zaleta wtyczki: uproszczenie dostępu do obiektu [eventBus] wyeksportowanego przez skrypt [./event-bus.js];
  • należy zauważyć, że wtyczka nie musi nazywać się [event-bus.js]. Można by ją nazwać na przykład [plugin-event-bus];
  • należy również zauważyć, że symbol $ w nazwie [$eventBus] jest konwencją służącą do oznaczenia właściwości [Vue], które zostały dodane za pomocą wtyczek. Nie ma obowiązku przestrzegania tej konwencji. W niniejszym tekście będziemy się jej jednak trzymać;

11.2. Główny skrypt [main.js]

Skrypt [./plugins/event-bus.js] definiuje wtyczkę dla frameworka [Vue.js]. Ta wtyczka nie jest jeszcze używana, a jedynie zdefiniowana. Aktywuje ją skrypt [main.js]:


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

// wtyczki
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);

// konfiguracja
Vue.config.productionTip = false

// instancjonowanie projektu [App]
new Vue({
  render: h => h(App),
}).$mount('#aplikacja')

Komentarze

  • wiersze 14–16 aktywują wtyczkę [PluginEventBus]. Po wierszu 16 wszystkie instancje klasy (funkcji) [Vue] posiadają właściwość [$eventBus], która dla każdej z nich wskazuje na ten sam obiekt eksportowany przez skrypt [./event-bus.js]. Tak będzie w przypadku każdego z komponentów projektu;

11.3. Widok główny [App]

Widok główny [App] pozostaje taki sam jak w poprzednim projekcie.

11.4. Komponent [Component1]

Komponent [Component1] wykorzystuje teraz swoją właściwość [$eventBus] do nasłuchiwania zdarzenia [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",
    // stan komponentu
    data() {
      return {
        data: "",
        showMsg: false
      };
    },
    // metody obsługi zdarzeń
    methods: {
      // obsługa zdarzenia [someEvent]
      doSomething(data) {
        this.data = data;
        this.showMsg = true;
      }
    },
    // zarządzanie cyklem życia komponentu
    // zdarzenie [created] – komponent został utworzony
    created() {
      // nasłuchiwanie zdarzenia [someEvent]
      this.$eventBus.$on("someEvent", this.doSomething);
    }
  };
</script>

Uwagi

  • w linii 33 wykorzystano właściwość [this.$eventBus] komponentu. Należy również zauważyć, że skrypt w linii 11 nie importuje już skryptu [./event-bus.js];

11.5. Komponent [Component2]

Komponent [Component2] wykorzystuje teraz swoją właściwość [$eventBus] do generowania zdarzenia [someEvent]:


<template>
  <div>
    <b-button @click="createEvent">Créer un événement</b-button>
  </div>
</template>
<!-- skrypt -->
<script>
  export default {
    name: "component2",
    // metody obsługi zdarzeń
    methods: {
      createEvent() {
        this.$eventBus.$emit("someEvent", { x: 2, y: 4 })
      }
    }
  };
</script>

Uwagi

  • wiersz 13, wykorzystanie właściwości [this.$eventBus] komponentu. Należy również zauważyć, że skrypt w wierszu 7 nie importuje już skryptu [./event-bus.js];

11.6. Komponent [Component3]

Komponent [Component3] ma ten sam kod co [Component1]. On również nasłuchuje zdarzenia [someEvent].

11.7. Uruchomienie projektu

Image

Otrzymujemy te same wyniki, co w poprzednim projekcie.