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.