Przesyłanie zdarzeń między komponentami w Vue 2

Jakiś czas temu miałem do zrobienie zadanie polegające na przechwyceniu zdarzenia w jednym komponencie, przykładowo Child 1 i wywołania funkcji w innym komponencie np. Child 2 (dla uproszczenia przyjmijmy, że komponenty Child 1, Child 2 były rodzeństwem, chociaż w rzeczywistości wspólny przodek położony był znacznie wyżej, powiedzmy, że był to praprarodzic). Komponenty te były używane w różnych miejscach w aplikacji i chodziło mi o jak najmniej „inwazyjne” i najprostsze rozwiązanie, żeby zminimalizować ryzyko wystąpienia błędu w innych częściach aplikacji. Rozwiązanie tylko dla tego jednego konkretnego kontekstu. Nie chciałem przy tym używać store (np. Vuex). Bardziej precyjnie, była to karta składająca się komponentów rozbudowanego formularza.

Sposób 1

Sensownym rozwiązaniem wydawało się emitowanie zdarzeń od komponentu Child 1 aż do wspólnego przodka, po czym przodek miałby przesyłać propsem wartość aż do swego potomka Child 2. Mniej więcej byłoby to coś takiego:

Sposób 2

Jak się okazuje, zadanie można rozwiązać prostszym sposobem. Mianowicie w Vue możemy wyemitować zdarzenie do roota i z dowolnego miejsca odwołać się do niego (property root dostępny jest z każdego miejsca). Wygląda to znacznie lepiej:

W komponencie Child 1 emitujemy zdarzenie w ten sposób:

this.$root.$emit("onChildComponentChange")

Następnie w komponencie, w którym chcemy wykonać jakąś funkcję, możemy wstawić np. w mounted:

mounted() {
  this.$root.$on('onChildComponentChange', this.componentMethod());
},

Poniżej zrobiłem interaktywne demo w Vue 2 z wykorzystaniem tych dwóch sposobów. Demo można pobrać z repozytorium (https://github.com/arturslab/emit-events-in-vue) aby zapoznać się z kodem.

Info: Masz jakieś pytania? Chciałbyś coś dodać do tego artykułu, czy też zauważyłeś jakieś błędy? Zostaw komentarz, a postaram się odpowiedzieć.

Udostępnij

Zobacz również

Komentarze

Subskrybuj
Powiadom o
guest

0 komentarzy
Inline Feedbacks
Zobacz wszystkie komentarze
0
Chętnie poznam Twoje zdanie, proszę o komentarzx