Komunikační vzory komponent Vue.js (bez Vuex) – část 3

Vzory vysílání směrem nahoru a dolů

V části 2 této série jsme použili vzory „$parent“ a „$children“, abychom umožnili komponentám komunikovat v tříúrovňové hierarchii. Ke konci jsme meli na mysli dotaz na jeste slozitejsi hierarchii komponent, nap. co když existuje deset úrovní komponent? Musíme udělat něco jako:

this.$parent.$parent.$parent.$parent.$emit('anyEvent', args);

Nemluvě o dětských komponentách může být obtížné sledovat.

To vede ke vzoru, který bude představen zde v části 3.

Za prvé, všechny ukázkové komponenty, se kterými jsme pracovali, tvoří datovou strukturu nazvanou Binární strom. Níže je obrázek z dokumentace Vue pro vnořené komponenty v paměti počítače, když je spuštěna aplikace Vue:

Zde je další binární strom s více úrovněmi:

Nyní předpokládejme, že máme tyto níže vnořené komponenty:



V App , svážeme událost s názvem change:font na Parent , funkce zpětného volání je handleChangeFont což aktualizuje velikost písma pro Parent a jeho potomci podle předané velikosti argumentu.

Parent je stejný jako předchozí příklady, udržuje seznam desserts a předá jej ChildA :

ChildA a GrandchildA jsou jednoduché, ChildA přijme rekvizitu a předá ji GrandchildA :

A takto aktuálně vypadá pohled:

Nyní pro některé obchodní požadavky chtějí uživatelé změnit velikost písma kliknutím na tlačítko s názvem Change Font Size v GrandchildA :

Můžeme tak učinit pomocí vzoru "$parent" z části 2:

Řádek 30 je vzor "$parent" v akci. Klikněte na tlačítko, velikost písma v zobrazení bude 20px:

Skvělé!

Ale jak vidíte, při složitosti vnořování bychom museli kódovat něco jako:

      this.$parent.$parent.$parent.$parent.$parent.$emit('change:font', '20px');

pokud uživatelé chtějí přidat toto tlačítko do komponenty grand-grand-grand-grandchild.

Lepší řešení ve velké stromové struktuře by se hodilo.

Vzor vysílání směrem nahoru

Pokud chce komponenta informovat komponentu předchůdce prostřednictvím spuštění jedné ze svých událostí, může tato komponenta doslova „vysílat“ směrem nahoru všem svým předkům o události, kterou chce spustit, a pokud má jedna komponenta předchůdce tuto konkrétní událost zaregistrovánu, provede funkce zpětného volání automaticky. Tento mechanismus událostí můžeme implementovat na Vue prototypový objekt, tedy všechny VueComponent instance k němu mohou mít přístup přes this .

V main.js , vytvoříme funkci s názvem $upwardBroadcast na Vue.prototype :

$upwardBroadcast funkce má dva parametry:

  • event :událost vysílaná směrem nahoru od aktuální komponenty
  • args :data předávaná při vysílání události

Bude vysílat událost od aktuální komponenty nahoru všem předkům, pokud má jeden předek ve vzestupné stromové hierarchii tuto událost zaregistrovánu, odpoví a provede funkci zpětného volání registrovanou samostatně s událostí. Pojďme to implementovat:

Nejprve na řádek 12 uložíme rodiče aktuální komponenty. Na řádcích 12 - 16, pokud rodič existuje, použije instanci rodiče k odeslání události, poté pokračuje k nadřazenému rodiči a rodiči rodiče atd.
while smyčka se zastaví, když už neexistuje žádný rodič, což znamená, že dosáhla nejvyššího (kořenového) uzlu stromu.

Nyní se podívejme, jak jej použít ke zlepšení předchozího vzoru „$parent“ v GrandchildA . Velmi jednoduché, jen jeden řádek změny:

Řádek 31 nahrazuje řádek 30 a používá $upwardBroadcast fungovat přes this a vysílá událost change:font a předá argument '20px' . Pokud klikneme na tlačítko, velikost písma se změní jako dříve:

Zvláštní poznámka

Zde říkám „používá $upwardBroadcast funkce přes this “, nikoli „zapnuto " this , protože $upwardBroadcast není definován na VueComponent instance vytvořená z VueComponent funkce konstruktoru, ale na Vue prototyp konstruktoru – jako to, co jsme dělali v main.js . Ano, lepší pochopení Vue.js vyžaduje solidní základy základů JavaScriptu, proto mám Vue tak rád – k práci nepoužíváte jen framework, ale můžete si upevnit a prohloubit základní znalosti JavaScriptu.

Ale když se nad tím trochu zamyslíte - jak to, že VueComponent instance má přístup k Vue prototyp konstruktoru? Ve skutečnosti Vue udělal jednu věc na vrcholu řetězce prototypů JavaScriptu - upravil tam, kde VueComponent.prototype body.

Také název funkce začíná $ znaménko, a to jen proto, že toto je konvence všech vestavěných vlastností a metod ve Vue.js.

Vzor vysílání směrem dolů

Nyní implementujme mechanismus sestupného vysílání. V main.js , vytvoříme další funkci s názvem $downwardBroadcast na Vue.prototype :

Má stejné dva parametry jako $upwardBroadcast a bude vysílat událost z aktuální komponenty směrem dolů všem potomkům, pokud má jeden potomek v sestupné stromové hierarchii tuto událost zaregistrovánu, odpoví a provede funkci zpětného volání. Můžeme tak učinit:

Nejprve získáme všechny potomky aktuální komponenty a pro každé dítě vyšle událost. Zde je to, co se liší od toho, že jedno dítě má v $upwardBroadcast pouze jednoho rodiče , je, že nyní může mít každé dítě mnoho dětí, takže pokud existují nějaké dětské složky současného dítěte, musíme zopakovat stejnou logiku, jak je vidět na řádku 28.

Toto je ideální případ pro rekurzi a pojďme to implementovat:

V těle funkce vytvoříme další funkci s názvem downwardBroadcast . Nejprve provedeme tuto funkci předáním this.$children aktuální komponenty pole, jak je vidět na řádku 33. Potom v rámci downwardBroadcast , procházíme pole dětí, a pokud jsou pod aktuálním potomkem děti, provedeme downwardBroadcast znovu předáním $children aktuálního potomka .

Nyní naše main.js vypadá takto:

Je čas to vidět v akci. Budeme vysílat směrem dolů událost s názvem show:year v App všem jeho potomkům po kliknutí na nové tlačítko s názvem Display current year a předaný argument je aktuální rok:

V ChildA , navážeme tuto událost na GrandchildA , funkce zpětného volání je ChildA.showYear() :

Klikněte na tlačítko, zobrazí se okno s upozorněním:

Vysílání je silné, že?

Zapouzdřit funkce (Háčky / styl kompozice)

Jedna věc, kterou můžeme zlepšit, je přesunout funkce v main.js do samostatného souboru - src/hooks/events.js ,
takže tento soubor obsahuje funkce, které vylepšují systém událostí na Vue.prototype :

Podle konvence pojmenování Hooks nebo Composition API vytváříme dvě nové funkce s názvem useUpwardBroadcast a useDownwardBroadcast , parametr je Vue funkce konstruktoru. V každém těle funkce je to předchozí definovaná funkce.

Nyní v main.js :

můžeme importovat tyto dvě funkce a spustit je pro vylepšení Vue.prototype , pokud potřebujeme.

V další části této série prozkoumáme další mocný vzor komponent Vue.js.

Zde jsou všechny články z této série:

Komunikační vzory komponent Vue.js (bez Vuex) – část 1

Komunikační vzory komponent Vue.js (bez Vuex) – část 2

Komunikační vzory komponent Vue.js (bez Vuex) – část 3

Komunikační vzory komponent Vue.js (bez Vuex) – část 4

Komunikační vzory komponent Vue.js (bez Vuex) – část 5

Komunikační vzory komponent Vue.js (bez Vuex) – část 6

Komunikační vzory komponent Vue.js (bez Vuex) – část 7