Vue pre jQuery používateľov – 1/2
REACT? ANGULAR? VUE!
Začíname s Vue ako náhradou za jQuery – predstavenie s príkladom.
Tento článok venujem predovšetkým programátorom, ktorí pri tvorbe web stránok používajú na front-ende zatiaľ len čisté HTML, CSS a JavaScript + jQuery, avšak aj bez ohľadu na aktuálne trendy sami cítia, že to nestačí a treba sa posunúť sa ďalej. Len ktorým smerom sa vydať? React? Angular? Vue? Meteor? Ember? Polymer? Riot? Knockout?
Neviem. To je na vás…
Názov článku, akokoľvek provokatívne znie, akokoľvek to vyzerá, že je o Vue, napriek tomu provokatívne znieť mal a je o Vue. Lenže … nie preto, že je Vue lepší ako tie zvyšné dva. Ale preto, že nejde ani o jeden z nich, ale naopak, ide o princíp, ktorý ich všetky tri spája – o reaktívne, znovupoužiteľné komponenty. A tento, v konečnom dôsledku nový prístup k tvorbe web stránok, najrýchlejšie pochopíte a naučíte sa používať práve s pomocou Vue. A to je neoddiskutovateľný fakt napriek všetkým prednostiam React a Angular.
No a podtitulok, na pohľad nezmyselný, lebo za týmto účelom Vue rozhodne nevznikol, len naznačuje spôsob, ktorý je v tomto článku použitý na vysvetlenie jeho funkčnosti. Avšak verím, že po prečítaní tohoto článku pochopíte, že má dokonca zmysel aj takéto jednoduché, na prvý pohľad kacírske použitie… Ale dosť bolo srandičiek a provokácií, poďme si to seriózne vysvetliť:
Prečo sa vybodnúť na jQuery
Dobre! Až teraz koniec srandičiek… Knižnicu jQuery snáď ani netreba predstavovať. Preto si ju predstavíme: je to knižnica, ktorá v zmysle hesla “Píš menej, rob viac” výrazne uľahčuje úlohy ako animácie elementov, alebo AJAX volania, a na zahodenie nie je ani zjednodušená registrácia udalostí, alebo manipulácia s obsahom či štýlom jednotlivých elementov. Suma sumárum dala vývojárom sadu nástrojov, ktoré im zjednodušili tvorbu “Web 2.0” stránok. Fakt zbožnujem kam až je schopný marketing zájsť… Proste stránok postavených nad AJAX-om. Princíp jej pomoci sa dá opísať ako “vytvor HTML a tu máš nástroje pomocou ktorých si”:
- Jednoduchým spôsobom vyber z dokumentu ľubovoľný element a
- jednoduchým spôsobom pre neho zaregistruj počúvanie na udalosť.
- Rovnako jednoduchým spôsobom na príslušnú udalosť načítaj na pozadí nový obsah a
- následne jednoduchým spôsobom ktorémukoľvek elementu zmeň obsah za nový.
- A prípadne aj jednoduchým spôsobom túto zmenu animuj.
To je prakticky všetko, čo jQuery prináša – selektory a metódy pre traverzovanie DOM, udalosti, AJAX, manipuláciu s DOM a animácie. Vývojárovi tak necháva plnú moc nad stránkou: prečo, kedy a ako sa načítajú údaje, aj kedy, kde a ako sa majú následne jednotlivé časti stránky prekresliť. Len mu poskytuje nástroje aby to urobil jednoduchším spôsobom ako čistým JavaScriptom – to je jeho najsilnejšou stránkou.
A jeho slabinou… Od vzniku jQuery už ubehlo vyše 10 rokov a za tú dobu stránky narástli na komplexnosti a s týmto vývojom vznikla zároveň potreba efektívnejšieho prístupu k ich tvorbe. Výsledkom sú frameworky ako React, Angular či Vue, ktoré túto potrebu riešia. Je ich samozrejme ďaleko viac ako tieto tri. Pravdou však ostáva, že React, Angular a Vue sú ďaleko najpopulárnejšie. A posledný menovaný si teraz predstavíme…
Čo je Vue
Začneme príkladom s jQuery… Predstavme si, že potrebujeme na stránke vykresliť tabuľku. Dajme tomu akože s aktuálne prihlásenými užívateľmi. A tlačítko “Obnov”, ktoré po kliknutí stiahne AJAX-om novú sadu údajov pre túto tabuľku. Ako sa to bežne rieši? Najčastejšie takto:
<div id="prihlaseni"> <button>Obnov</button> <table> <thead> <tr> <th>ID</th> <th>Meno</th> <th>Priezvisko</th> <th>Email</th> </tr> <thead> <tbody></tbody> </table> <div> <script src="https://unpkg.com/jquery@3.2.1/dist/jquery.min.js"></script> <script> var zdroj = 'https://api.mockaroo.com/api/a0829af0?count=20&key=6e3c5aa0' function nacitajAvykresli () { function vykresli (uzivatelia) { var riadky = '' uzivatelia.forEach(function (riadok) { riadky += '<tr>' Object.keys(riadok).forEach(function (stlpec) { riadky += '<td>' + riadok[stlpec] + '</td>' }) riadky += '</tr>' }) $('#prihlaseni tbody').html(riadky) } $.getJSON(zdroj).then(vykresli) } // Po nacitani stranky hned nacitaj a vykresli prihlasenych nacitajAvykresli() // A po kliknuti na "Obnov" ich znovu nacitaj a vykresli $('#prihlaseni button').click(nacitajAvykresli) </script>
[iframe src=”https://jsfiddle.net/provuecateur/qvdurqqm/embedded/result,html,js/” width=”100%” height=”560″]
Príklad je plne funkčný. Ak by vám predsa len nefungoval a nezobrazoval zoznam užívateľov, tak je to pravdepodobne tým, že má mockaroo.com problém s certifikátom. Kliknite na nasledovné url zdroja údajov ( https://api.mockaroo.com/api/a0829af0?count=20&key=6e3c5aa0 ) – otvorí sa v novom okne – a potvrďte bezpečnostnú výnimku. Že to funguje sa prejaví tak, že vám z tej url stiahne json súbor. Ten len zmažte, zatvorte kartu a znovu spustite fiddle prepnutím sa z karty Result na napríklad na kartu HTML a potom späť na Result.
Naspäť k veci. Kód síce funguje, ale takto sa to robiť nemá. Mám na mysli, že funkcia “nacitajAvykresli” volá globálnu premennú “zdroj” priamo, bez toho aby sa jej odovzadala cez parameter. Rozumnejšie by bola napísaná a zavolaná takto:
var zdroj = 'https://api.mockaroo.com/api/a0829af0?count=20&key=6e3c5aa0' function nacitajAvykresli (url) { function vykresli (uzivatelia) { var riadky = '' uzivatelia.forEach(function (riadok) { riadky += '<tr>' Object.keys(riadok).forEach(function (stlpec) { riadky += '<td>' + riadok[stlpec] + '</td>' }) riadky += '</tr>' }) $('#prihlaseni tbody').html(riadky) } $.getJSON(url).then(vykresli) } // Po nacitani stranky hned nacitaj a vykresli prihlasenych nacitajAvykresli(zdroj)
A kde je koniec? Tu je prvý kameň úrazu. Priemerný užívateľ jQuery bude mať okamžite problém, o čom svedčí neustále pokladanie nasledovnej tejto otázky na stackoverflow: ako tú funkciu aj s parametrom odovzdám metóde “click”? Takto mi to nechce ísť:
$('#prihlaseni button').click(nacitajAvykresli(zdroj))
Že sa vôbec divíš… Pritom riešenie je tak jednoduché:
$('#prihlaseni button').click(nacitajAvykresli.bind($, zdroj))
Také riešenie však predpokladá o dosť hlbšie znalosti princípov JavaScriptu, niečoho, od čoho sa vás jQuery tak vehementne snaží “ochrániť”. A takto “obrnený voči znalostiam” nieto divu, že sa vo výslednom kóde dopustíte ďalších prehreškov.
Na pohľad je jasné v čom jQuery pomôže – registrácia spätného volania na udalosť “onclick”, načítanie údajov AJAX-om a manipulácia s DOM – obsahom značky TBODY. Ale funkciu “vykresli” – čiže kedy, kde a ako získané údaje vykreslíme, v tom nám necháva slobodu. Presne ako sme si spomínali v úvode. Prax však ukázala, že nám tým necháva nie len slobodu, ale predovšetkým zodpovednosť. Napríklad za efektivitu. A tá pokrivkáva už len v tak jednoduchom prípade, akým je tento príklad…
Prečo? Tak hneď to “skladanie obsahu” do textovej premennej. To, že k nej v cykle pripájame ďalší a ďalší obsah. Treba si uvedomiť, že v konečnom dôsledku nič nepripájame, lebo v JavaScripte sú textové premenné immutable.
A čo následné vykreslenie? Len čo zavoláme funkciu “$(‘#prihlaseni tbody’)” prehliadač prelezie celý DOM model, aby našiel náš element. A po kliknutí na “Obnov” to urobí znovu a znovu a …
Poďme ďalej: čo ak klikneme na “Obnov”, ale nikto nový sa neprihlásil ani neodhlásil? Čiže sa nám vrátia tie isté údaje, ktoré už máme zobrazené? No čo asi. Budeme vyskladávať v cykle obsah premennej, traverzovať celý DOM model a nahradíme TBODY obsahom premennej, na čo následne prehliadač zareaguje parsovaním zmeneného DOM modelu. To znie vážne efektívne…
Kým však problém s neustálym traverzovaním DOM sa dá jednoducho vyriešiť tak, že funkciou “$(‘#prihlaseni tbody’)” vrátený element uložíme do premennej a následne budeme metódu “html” používať nad tou premennou (a to sa stavte, že aj tú bude niekto do funkcie “nacitajAvykresli” rvať priamo, nie parametrom), tak problém so zbytočným vykreslovaním vyriešime jedine tak, že načítané udaje tiež uložíme do premennej a po prípadnom načítaní nových údajov ich najskôr porovnáme s predošlou sadou a až potom ich, možno, prekreslíme. Ale ako porovnať pole objektov? Či na nejakom indexe, v hodnote niektorého kľúča došlo k zmene? Ďalšia funkcionalita na ktorú by ste mali myslieť a sami implementovať…
Zhrňme si to: plytvanie RAM, neustále traverzovanie a neustále parsovanie DOM – to je kód našej úžasne jednoducho generovanej dynamickej tabuľky v stránke, ktorá nám na mobile za pol hodinu vytrieska baterku. Ale takto to proste s jQuery chodí. Máme s ním slobodu. A len málokto si uvedomuje, že to v konečnom dôsledku znamená zodpovednosť. A to zrovna za tie najdôležitejšie úlohy. A to sme po tej tabuľke nechceli aby bola zoraditeľná, napríklad kliknutím na názov stĺpca. Aj to sa dá velice rýchlo napísať neefektívne, lebo jQuery nám s tým pomôže akurát tak zaregistrovaním udalosti “onclick”. A keby ste ešte nebodaj chceli aby sa to zoradenie vykonalo animovane, že sa pri zoradení tabuľka neprekreslí, ale presunú sa jednotlivé riadky, hneď si zavaríte na layout trashing…
A toto je tá slabina jQuery. Nie je zlá sama o sebe. To čo robí, robí dobre. Ale keď sa nad tým hlbšie zamyslíte, jej prínos je minimálny, zato však priam zvádza k písaniu neefektívneho kódu. Ešte aj s jednoduchou stránkou, napríklad s našim príkladom, vám pomôže len minimálne a gro jej funkčnosti je čisto na vás. A na rozsiahlejšie projekty už vyslovene nestíha s dychom. Pri rozsiahlejšom projekte zistíte, že ste si takmer všetko naprogramovali sami a len kde-tu zavolali nejakú funkciu či metódu jQuery. Na rozsiahlejšie projekty proste nemá veľké opodstatnenie z dôvodu filozofie nad ktorou bola postavená. Na také projekty je vhodnejší práve spomínaný Vue. Rovnako z dôvodu filozofie nad ktorou je postavený. Naprosto opačnou ako “ctí” jQuery… Paradoxne, napriek úplne odlišnému princípu, hoci to fakt vyzerá ako miešanie hrušiek s jablkami, Vue dokáže jQuery zastúpiť. Dokonca je Vue vhodné, ak nie vyslovene vhodnejšie, aj na malý projekt, kde by človek zvyčajne siahol ako prvé po jQuery… Ale nebudem vás napínať. Poďme si náš príklad s generovaním tabuľky prepísať s jeho pomocou – ukážme si konečne čo je Vue:
V pokračovaní článku, zatiaľ dovi.