10. projekt [vuejs-08]: zdarzenia niezależne od hierarchii komponentów, cykl życia komponentów
Projekt [vuejs-08] pokazuje, w jaki sposób komponenty, które nie są bezpośrednio powiązane w hierarchii komponentów, mogą mimo to komunikować się za pośrednictwem zdarzeń. Struktura drzewa projektu [vuejs-08] przedstawia się następująco:

10.1. Główny skrypt [main.js]
Skrypt [main.js] pozostaje taki sam jak w poprzednich przykładach.
10.2. Skrypt [even-bus.js]
Skrypt [event-bus.js] to narzędzie, którego będziemy używać do generowania i nasłuchiwania zdarzeń:
import Vue from 'vue';
const eventBus = new Vue();
export default eventBus;
Skrypt [event-bus] ogranicza się do utworzenia instancji klasy [Vue] (wiersze 1–2) i jej wyeksportowania (wiersz 3). Klasa [Vue] posiada dwie metody do obsługi zdarzeń:
- [Vue].$emit(nazwa, dane): umożliwia wygenerowanie zdarzenia o nazwie [nom], powiązanego z danymi [donnée];
- [Vue].$on(nazwa, funkcja): umożliwia przechwycenie zdarzenia o nazwie [nom] i przekazanie go do przetworzenia przez funkcję [fn]. Funkcja [fn] otrzyma jako parametr dane [donnée] powiązane z tym zdarzeniem przez jego nadawcę;
Taka obsługa zdarzeń nie jest powiązana z hierarchią komponentów. Wystarczy, aby komponenty, które chcą się w ten sposób komunikować, korzystały z tej samej instancji klasy [Vue] do wysyłania i nasłuchiwania zdarzeń. W naszym przykładzie wykorzystamy instancję [eventBus] zdefiniowaną przez poprzedni skrypt [event-bus.js].
10.3. Widok główny [App.vue]
Kod widoku głównego [App] wygląda następująco:
<template>
<div class="container">
<b-card>
<b-alert show variant="success" align="center">
<h4>[vuejs-08] : événements indépendants de la hiérarchie des composants, cycle de vie des composants</h4>
</b-alert>
<!-- trzy komponenty komunikujące się za pomocą zdarzeń -->
<Component1 />
<Component3 />
<Component2 />
</b-card>
</div>
</template>
<script>
import Component1 from "./components/Component1";
import Component2 from "./components/Component2";
import Component3 from "./components/Component3";
export default {
name: "app",
// komponenty
components: {
Component1,
Component2,
Component3
}
};
</script>
- wiersze 8–10: widok główny [App] wykorzystuje trzy komponenty [Component1, Component2, Component3], które będą komunikować się za pomocą zdarzeń. Wszystkie trzy komponenty znajdują się na tym samym poziomie w widoku [App]. Ponadto nie będzie między nimi żadnej relacji hierarchicznej;
10.4. Komponent [Component1]
Kod komponentu [Component1] jest następujący:
<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>
import eventBus from "../event-bus.js"
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]
eventBus.$on("someEvent", this.doSomething);
}
};
</script>
Uwagi
- wiersze 4–6: alert wyświetlający dane [data] z wiersza 18. Dane te zostaną zainicjowane przez procedurę obsługi zdarzenia [doSomething] z wiersza 25. Ten menedżer jest aktywowany po otrzymaniu zdarzenia [someEvent] (wiersz 34). Powiadomienie jest wyświetlane warunkowo w zależności od wartości atrybutu [showMsg] w wierszu 19. Atrybut ten jest również ustawiany przez menedżera zdarzeń [doSomething] w wierszu 25;
- wiersz 32: funkcja [created] jest menedżerem zdarzeń. Obsługuje ona zdarzenie [created], które jest generowane w trakcie cyklu życia komponentu. Istnieją również inne zdarzenia, np. [beforeCreate, created, beforeMount, mounted, beforeUpdate, updated, beforeDestroy, destroyed]. Zdarzenie [created] jest generowane w momencie utworzenia komponentu;
- wiersz 12: importowana jest instancja [eventBus] klasy [Vue];
- wiersz 34: jest ona wykorzystywana do nasłuchiwania zdarzenia [someEvent]. Gdy zdarzenie to wystąpi, wywoływana jest metoda [doSomething] z wiersza 25;
- wiersz 25: metoda [doSomething] otrzymuje jako parametr [data] dane, które nadawca zdarzenia [someEvent] powiązał ze zdarzeniem;
- wiersze 26–27: stan komponentu zostaje zmodyfikowany tak, aby alert z wierszy 4–6 wyświetlał otrzymane dane;
10.5. Komponent [Component2]
Komponent [Component2] wygląda następująco:
<template>
<div>
<b-button @click="createEvent">Créer un événement</b-button>
</div>
</template>
<!-- skrypt -->
<script>
import eventBus from '../event-bus.js'
export default {
name: "component2",
// metody zarządzania zdarzeniami
methods: {
createEvent() {
eventBus.$emit("someEvent", { x: 2, y: 4 })
}
}
};
</script>
Komentarze
- wiersz 3: przycisk służący do utworzenia zdarzenia. Gdy użytkownik kliknie ten przycisk, wywoływana jest metoda [createEvent] z wiersza 13;
- wiersz 8: importowana jest instancja [eventBus] zdefiniowana przez skrypt [event-bus.js];
- wiersz 14: ta instancja służy do wygenerowania zdarzenia o nazwie [someEvent] powiązanego z danymi [{ x: 2, y: 4 }]. Ostatecznie, gdy użytkownik kliknie przycisk w wierszu 3, generowane jest zdarzenie o nazwie [someEvent]. Jeśli przypomnimy sobie definicję [Component1], to właśnie ona przechwyci to zdarzenie;
10.6. Komponent [Component3]
Kod tego komponentu jest następujący:
<template>
<b-row>
<b-col>
<b-alert show
v-if="showMsg">Evénement [someEvent] intercepté par [Component3]. Valeur reçue={{data}}</b-alert>
</b-col>
</b-row>
</template>
<script>
import eventBus from "../event-bus.js"
export default {
name: "component3",
// stan komponentu
data() {
return {
data: "",
showMsg: false
};
},
methods: {
// zarządzanie zdarzeniami [someEvent]
doSomething(data) {
this.data = data;
this.showMsg = true;
}
},
// zarządzanie cyklem życia komponentu
// zdarzenie [created] – komponent został utworzony
created() {
// nasłuchiwanie zdarzenia [someEvent]
eventBus.$on("someEvent", this.doSomething);
}
};
</script>
[Component3] jest klonem komponentu [Component1]. Został on umieszczony wyłącznie w celu pokazania, że jedno zdarzenie może być przechwycone przez wiele komponentów.
10.7. Uruchomienie projektu [vuejs-08]


