Kreiranje komponente
Poznato je da čak i kod najjednostavnijih aplikacija nije dobro držati ceo kod u jednom fajl, već je bolje razbiti ga na više celina jer se na taj način pojednostavljuje aplikacija i omogućava bolja preglednost kao i lakši debuging. Upravo su komponente odličan način da se razbije kompleksnost aplikacije na manje delove. Pored toga komponente nam omogućavaju da enkapsuliramo kod naš kod, kao i da ga možemo koristiti više puta u aplikaciji (reusable kod).
U suštini komponenta predstavlja jedan options objekat Vue instance. Ukoliko nam je dostupna ES6 sintaksa i korišćenje modula, onda je dobro taj options objekat izdvajiti u zaseban fajl. Taj fajl u okviru Vue.js framework-u ima specijalnu ekstenziju .vue, a naziv po konvenciji mora da započinje velikim slovom i sastoji se iz tri sekcije: template, script, style.
Primer: ButtonCounter.vue
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 |
<template> <div> <button v-on:click="count++">Klikni me</button> <p>kliknuto {{ count }} puta </p> </div> </template> <script> export default { data() { return { count: 0 }; } }; </script> <style> button { font-size: 1rem; background-color: red; color: white; padding: 0.3rem 0.8rem; } </style> |
Prednosti korišećenja komponenti su sledeće:
- Syntax highlighting
- Component-scoped CSS
- Preglednija aplikacija zbog modularnog programiranje
NAPOMENA:
Za Vue verziju 2.0 template sekcija mora da ima samo jedan root element, u susprotnom Vue.js izbacuje error.
1 2 3 4 |
<template> <button v-on:click="count++">Klikni me</button> <p>kliknuto {{ count }} puta </p> </template> |
Prethodni primer izbacuje error, jer postoje dva root elementa u okviru template. Rešenje je da stavimo oba elementa u zajednički wrapper element:
1 2 3 4 5 6 |
<template> <div> <button v-on:click="count++">Klikni me</button> <p>kliknuto {{ count }} puta </p> </div> </template> |
Registrovanje komopnente
Da bi mogli implementirati kreiranu komponentu u našu aplikaciju (ili u drugu komponentu) potrebno ju je registrovati (mora da ima konstruktorsku funkciju na osnovu koje se generiše).
a) Globalno registrovanje komponente
Globalno registrovanje komponente nam omoućava da komponentu koristimo iz različitih Vue instanci ili drugih komponenti. Komponentu registrujemo koristeći component() metodu. Ova metoda prihvata dva argumenta: naziv tag-a i options objekat:
1 2 3 4 5 |
const app = Vue.createApp({}) app.component('naziv_komponente', {/* options objekat */}) app.mount('#app') |
Primer
See the Pen
Untitled by Web programiranje (@chos)
on CodePen.
1 |
Vue.component('naziv-taga', { /* options objekat */ } |
Primer
1 2 3 4 5 6 7 8 |
Vue.component('button-counter', { data: function () { return { count: 0 } }, template: '<button v-on:click="count++">Stisnuli ste dugme {{ count }} puta.</button>' }) |
b) Lokalno registrovanje komponente
Za razliku od globalne registacije komponente, kada su komponente dostupne svim drugim komponentama, kod lokalno registrovane komponente sadržaj jedne komponente nije odmah dostupan u okviru druge komponente, potrebno je dodatno importovati i lokalno registrovati komponentu.
Pri lokalnoj registraciji se ne koristi metoda component() nego components svojstvo. To svojstvo je objekat kroz koji se definišu sve lokalne komponente u vidu paraova key/value. Kroz key se definiše naziv komponente, a value ukazuje na promenjivu koja predstavlja options objekt:
1 2 3 4 5 6 |
new Vue({ el:"#app", components: { 'button-counter' : { /* options objekat */ } } }) |
ili da izdvojimo options objekat (važno kod “Single File Component”)
1 2 3 4 5 6 7 8 |
var button-counter-options = { /* options objekat */ } new Vue({ el:"#app", components: { 'button-counter' : button-counter-options } }) |
“data” svojstvo u Vue komponenti
Svojstvo “data” u komponentama ne može da bude običan objekat, jer je Vue.js dizajniran da u tom slučaju izbaci error. Razlog zbog čega Vue.js sprečava takvu sintaksu (koja je inače regularna za u okviru Vue instance), je taj što bi se tako definisan objekat delio u svim kreiranim instancama! Da bi se to izbeglo potrebno je da podatke deklarišemo kao funkciju koja vraća objekat sa data svojstvima, nakon čega će svaka instanca komponente dobiti svoju novu kopiju početnog “data” objekta.
1 2 3 4 5 |
data: function (){ return { message: "Hello" } } |
ili ako smo u mogućnosti da koristimo ES6, možemo napisati jednostavanije:
1 2 3 4 5 |
data() { return { message: "Hello" }; } |
Primer
See the Pen Komponente by Web programiranje (@chos) on CodePen.
NAPOMENA:
Kada bi smo ipak želeli da delimo isti data objekat kroz više instanci, postoji način da “zaznemo” Vue.js. Potrebno je da izvučemo data objekat izvan vue istance i dodelimo ga nekoj promenjivoj, pa data svojstvu ukažemo na tu promenjivu:
See the Pen Komponente i zajedniki data objekat by Web programiranje (@chos) on CodePen.
Ukoliko bi vratili data objekat u instancu, svaka komponenta bi tada imala svoj data objekat, nakon čega bi brojači bili razdvojeni.
1 2 3 |
components: { 'naziv-komponente' : { /* options objekat */ } } |
Primer
See the Pen
Lokalne komponente by Web programiranje (@chos)
on CodePen.
NAPOMENA:
Kada se koristi single file komponenta ona se nalazi u zasebnom fajlu pre registrovanja je neophodno da je prvo importujemo (pogledaj primer):
1 |
import ButtonCounter from './ButtonCounter.vue' |
Implementacija komponente u HTML
<template> tag
Vue aplikacija može da ubaci novi element u HTML. Mesto dodavanja novog HTML elementa se obeležava sa ubacivanjem <template></template> taga:
1 2 3 |
<div id="app"> <template></template> </div> |
Ovaj element ne postoji sve dok se ne kreira Vue instanca. Sa čime će se zameniti template tag kada se kreira Vue instanca se definiše u okviru “template” svojstva instance:
1 2 3 |
let app = Vue.createApp({ template: `<p>{{msg}}</p>` }) |
Primer
See the Pen
Vue template by Web programiranje (@chos)
on CodePen.
<Komponent> tag
Komponente se slično implementiraju kao i <template> tag, dovoljno je ugraditi custom tag sa nazivom komponente i on će sa sobom “doneti” svoje HTML elemente, svu logiku, i stajling definisan u komponenti.
1 2 3 |
<div id="app"> <naziv-komponente></naziv-komponente> </div> |
U aplikaciji se mogu koristi više instanci iste komponente, za to je dovoljno da se tag sa nazivom komponente ubaci na više mesta u okviru samog HTML-a.