Vue.js alapozó
A Vue.js a React.js és az Angular után a 3. legkedveltebb JavaScript keretrendszer. Népszerűségén sokat lendített az, hogy sok más nagy név mellett beállt mögé a Laravel (legkedveltebb PHP keretrendszer) csapata is. Ha hirtelen pozicionálni kellene a rendszert, akkor azt mondanám, hogy leginkább a Google féle AngularJS-hez hasonlít, ami nem is csoda, hisz a Vue fejlesztését elindító Evan You azelőtt AngularJS fejlesztő volt a Google-nél. Elmondása szerint szeretett volna egy pehelysúlyú rendszert létrehozni az AngularJS előnyeinek megtartásával.
Én igazából egy webes hobbiprojekt kapcsán futottam bele a keretrendszerbe. Mivel nem vagyok nagy frontend mágus (mobil appokat és backendet fejlesztek főleg), ezért általában Bootstrap-et használok a weboldalakhoz és jQuery-vel rakom alá a működést. Bár nagyon szeretem a jQuery-t mert sok mindent leegyszerűsít és van hozzá egy rakás komponens, azért akad vele néhány gond is. Az egyik problémám az volt hogy akárhogy csinosítottam, a jQuery-s kód kicsit komplexebb működési logikánál már kusza volt és nem jól áttekinthető. A másik dolog ami kezdetektől fogva zavart, hogy a jQuery CSS selectorokkal dolgozik így a működési logika “kívülről van rárakva” a HTML elemekre. Ennek eredményeként ha valaki ránéz a HTML kódra, halvány lila gőze nem lesz róla, hogy hol van eseménykezelő (pl. mit csinál a gomb ha megnyomom), hol jelennek meg dolgok, stb. Ez egy kicsit komplexebb oldal esetén már meg tudja nehezíteni egy új fejlesztő dolgát, mivel úgy kell összehalászni a JavaScript kódból a CSS selectorok alapján, hogy mi mit csinál. Nézzünk is erre egy nagyon egyszerű példát:
Ha csak a HTML kódot nézzük a script rész nélkül, akkor semmit nem látunk, csak hogy van egy gomb meg egy szöveg egy span-ban, de hogy ezek mit csinálnak, egyáltalán csinálnak-e valamit, azt úgy kell összevadászni a script részből.
Volt tehát egy Bootstrap-es HTML kódom jQuery-vel, amit szerettem volna átalakítani valami sokkal elegánsabbra. A React-ot és az Angular-t hamar elvetettem, mivel ezeket nem olyan egyszerű csak úgy hozzáadni a meglévő HTML kódhoz. A React-nál ugye kötelező a JSX használata, ami olyan mint a HTML, de nem az! Az Angular (nem összetévesztendő az AngularJS-el) meg eleve TypeScriptet használ és tök más a logikája. Maradt tehát a Vue.js, amiről ráadásul azt mondták a GitHub oldalon, hogy “incrementally-adoptable”, tehát kis darabonként cserélhetem le a jQuery kódjaimat, vagy akár meg is tarthatom a jQuery-t ott ahol akarom és használhatom őket keverve. No, hát pont ez az ami kellett nekem. Annál is inkább, mert használtam pár jQuery komponenst (térképes autocomplete, lokalizáció, autocomplete, stb.) amiket baromira nem akartam kidobni vagy hasonlót keresni. Így esett tehát a választás a Vue.js-re.
Indulásnak nézzük meg a fenti jQuery kód Vue.js változatát:
Ami talán egyből feltűnik, hogy itt már a HTML kódban szépen látszik a működés. A gombon van egy click eseménykezelő, ami a btnClick függvényt fogja meghívni, a span-ban pedig van egy {{msg}} blokk, ahová majd lesz valami írva. Emellett maga a kód szép, egyszerű és átlátható. A data-ban vannak a változók, a methods-ban az eseménykezelők, ha pedig változtatni akarunk valamit, egyszerűen felülírjuk a változót (erről még majd lesz szó). Ami az “incrementally-adoptable”-t illeti, láthatjuk, hogy van egy “el” opció Vue objektum konstruktorában, amivel azt tetszőleges HTML elemhez rendelhetjük, így megtehetjük, hogy a HTML oldalunknak csak egy-egy részét “Vue-sítjük”. Szuper!
Most hogy megvan életünk első Vue.js-es HTML oldala, nézzük meg kicsit közelebbről a kódot. Amikor létrehozzuk a Vue komponenst, az értelmezi az “el”-ben átadott HTML blokk kódját, hozzárendeli az eseménykezelőket a HTML objektumokhoz, és kitölti a {{}}-es részeket. Mikor megnyomjuk a gombot, a btnClick függvény hívódik meg, ami simán csinál egy értékadást. De mitől fog megváltozni a span-ban lévő szöveg? Nos, a trükk az, hogy a this.msg valójában nem egy változó, hanem egy JavaScript property, aminek ha értéket adunk akkor egy függvény hívódik meg. Ez a függvény írja át a span tartalmát. Ez ugyanaz a reaktív megoldás amit a React.js is használ, csak kicsit tisztább, mert nem kell setState függvényt hívni, elég beállítani a változó értékét (a React-ról itt írtam bővebben). Ugyancsak a React-hoz hasonlóan a változások itt is a memóriában történnek (Virtual DOM) és a rendszer csak a változásokat alkalmazza aszinkron módon a tényleges HTML objektumokon (DOM), így sokkal gyorsabb és hatékonyabb a működés.
Az egyszerű példa után nézzünk egy kicsit bonyolultabbat, egy TODO appot, ahol már jobban kijön a Vue.js előnye a jQuery-vel vagy a vanilla JS-el szemben.
A fenti mintából már jól látszik, hogyan lehet Vue.js segítségével minimális kódból jópofa dolgokat csinálni. Egy todo app-hoz elég felvennünk egy todoText reaktív változót amit a v-model direktíva segítségével egy input mezőhöz rendelünk, valamint egy todos tömböt, amin a v-for direktíva segítségével iterálunk végig. Az addItem függvény egyszerűen hozzáadja a todos tömbhöz a todoText tartalmát, majd törli azt (aminek hatására törlődik a hozzá kötött input box tartalma is), a removeItem pedig a tömb indexe alapján törli az elemet. Mivel a todos tömb egy reaktív változó, ezért annak minden változása újrafuttatja a v-for-os ciklust és frissíti a DOM-ot. Képzeljük el, hogyan nézne ki ugyanez DOM manipulációkat használva jQuery vagy vanilla JS segítségével…
Amiről még írni szeretnék ebben a kis kedvcsinálóban, az a Vue.js komponens architektúrája. A Vue.js filozófiája, hogy a komponensek legyenek egységbe zártak, így lehetőség van arra, hogy a komponens HTML kódját, a működési logikát és az esetleges CSS style-okat kipakoljuk egyetlen vue fájlba, és azt használjuk a kódunkban. Ezt demonstrálandó módosítani fogjuk a fenti kódot és a TODO listánkból csinálunk egy komponenst. Ehhez hozzunk létre egy todo.vue fájlt a következő tartalommal:
Ahogyan a fenti példában is látható, egy vue fájl 3 részből áll. A template rész tartalmazza a komponens HTML kódját. Ide egyszerűen csak bemásoltuk a HTML kódot az előző példából. Ezt követi a script rész, ami a működési logika. Itt annyi a különbség, hogy a data rész itt objektum helyett függvény, de ezt leszámítva ugyanaz. A fájl végén van egy style rész. Ide jöhetnek a komponenshez köthető CSS formázások.
A komponens behúzását és használatát a következő kódrészlet mutatja:
Ami itt újdonság az a http-vue-loader script behúzása, ami a vue fájlok futásidőben történő betöltését teszi lehetővé, valamint a components rész a Vue konstruktorában. Ez utóbbi, ahol megadjuk a komponens nevét (todo), amit aztán sima HTML tagként használhatunk a “Vue-sített” blokkban.
Nagyon dióhéjban ennyit szerettem volna írni a Vue-ról. És hogy merre tovább? Mindenek előtt érdemes átolvasni a Vue dokumentációját, ami részletesen végigvezet minket a lehetőségeken. Ezen kívül rengeteg Vue tutorial és tananyag található a neten, valamint a népes közösségnek hála hamar választ kaphatunk a StackOverflow-n feltett kérdésekre. Bár a fenit példákban én simán script tagekkel húztam be a Vue librarykat, éles környezetben érdemes npm-et és webpack-et használni, ami előfordítja a vue fájlokat, valamint optimalizálja és egyetlen böngésző független fájlba fűzi össze a JavaScript részeket. Van egy Laravel Mix nevű eszköz, ami Laraveltől függetlenül is működik és nagyon egyszerűvé teszi a Webpack használatát. Ha tehát komoly Vue fejlesztésbe kezdünk érdemes megismerkedni ezzel vagy a Vue által fejlesztett parancssoros környezettel. Nemrégiben írtam egy cikket a Parcel.js nevű toolról, ami ugyancsak nagyon meg tudja könnyíteni a Vue projektek fejelsztését. Van egy Vuera nevű projekt, ami React komponensek használatát teszi lehetővé Vue-ban, így ha valaki Reactról szeretne váltani, vagy egyszerűen csak ki szeretné használni a React közösség által fejlesztett népes komponens palettát, annak ez megfelelő megoldás lehet. Aki esetleg mobil appot szeretne fejleszteni Vue alapon, annak érdemes vetni egy pillantást a Vue Native projektre (itt írtam róla egy teljes bejegyzést), ami egy plusz réteg React Native felett (itt írtam róla részletesen). A template-ekben React komponensekből építkezhetünk és a végeredmény egy natív applikáció (nem csomagolt webapp) lesz.
Nyilván rengeteg dolgot lehetne még írni a Vue.js-ről, de kedvcsinálónak úgy gondolom ennyi elegendő. Ahogy a fentiekből látható, a rendszer szépen felépített, könnyen tanulható és fokozatosan beépíthető bármilyen létező projektbe. Ha szükséges, nagyon szépen együtt tud működni jQuery-vel, vagy más JavaScript könyvtárakkal, persze csak akkor, ha odafigyelünk a DOM kezelésre. Összességében tehát csak ajánlani tudom, hogy minél többen próbáljátok ki ezt a nagyon kezes kis reaktív keretrendszert.