Lekce 3 - Data a props v komponentách ve Vue
V minulé lekci, Komponenty ve Vue, jsme se seznámili s Vue komponentami, jejich strukturou a použitím v aplikaci. Vytvořili jsme první Vue komponenty, které budeme v naší kalkulačce dále používat.
Dnes naplníme naše komponenty daty. Naučíme se zobrazovat data v šablonách, předávat data z rodičovských do dceřiných komponent a validovat je.
Data
Zelené pole v prvním řádku naší kalkulačky bude zobrazovat text. Tak, jak bude uživatel klikat na tlačítka, bude se v zeleném poli objevovat číslo, které má být prvním členem aritmetické operace. Text bude dále obsahovat operátor a poté druhé číslo. Nakonec se za text ještě zařadí rovnítko a vypočítaný výsledek.
Je tedy zřejmé, že uvnitř komponenty TheLayout
budeme
potřebovat proměnnou, do které budeme průběžně ukládat zobrazovaný
text, a hodnotu této proměnné budeme potřebovat zobrazovat v šabloně. Vue
nám k tomuto účelu nabízí součást konfiguračního objektu s názvem
data.
V první řadě si řekněme, že data
jsou metodou, nikoliv
vlastností konfiguračního objektu. Data zkrátka musí být funkcí, je to
syntaktická podmínka frameworku VueJS. Tato funkce musí vracet objekt, jehož
vlastnostmi jsou jednotlivé proměnné, které potřebujeme zobrazit v
šabloně nebo s nimi dále pracovat v metodách dané komponenty. Upravme
skript komponenty TheLayout
takto:
export default { name: 'TheLayout', data () { return { value: '0' } } }
Proměnná value
nyní obsahuje textový řetězec
"0"
a je připravena pro zobrazení v šabloně.
Použití dat v šablonách
Ve Vue zobrazujeme hodnoty proměnných v šabloně pomocí zdvojených
složených závorek takto {{ value }}
. Uvnitř závorek může
být jakákoliv hodnota proměnné, kterou zná konfigurační objekt
komponenty, stejně tak libovolný JavaScriptový výraz.
Kód:
<div>{{ 1 + 2 }}</div>
nám tedy v elementu <div>
zobrazí hodnotu
"3"
, kód:
<div>{{ '1' + '2' }}</div>
zobrazí hodnotu string "12"
a kód:
<div>{{ value === 0 ? 'A' : 'B' }}</div>
zobrazí písmeno "A"
, pokud je hodnotou proměnné
value
číslo 0
, anebo písmeno "B"
ve
všech ostatních případech.
Je nicméně dobrou praxí do šablon nepsat složité výrazy, znesnadňuje to čitelnost kódu. Je obecně doporučováno, aby aplikační logika, a tedy i výpočet zobrazovaných hodnot, byla obsažena výhradně ve skriptu.
Vraťme se k naší kalkulačce a upravme 5. řádek souboru
TheLayout.vue
takto:
<div class="display">{{ value }}</div>
V zeleném poli prvního řádku kalkulačky nyní uvidíme zobrazenou nulu.
Props
Jediné tlačítko, které naše kalkulačka zatím obsahuje je písmeno "C".
Je tomu tak proto, že jsme tento znak natvrdo nakódili do HTML šablony.
Jistěže bychom mohli v komponentě CalculatorButtons
vytvořit v
rámci dat proměnnou, do níž bychom uložili text "C", a tuto proměnnou pak
zobrazovat v šabloně výše uvedeným způsobem. To se nám však příliš
nehodí, potřebujeme totiž, aby tlačítko zobrazovalo různé hodnoty, a to
podle toho, jak je nastavíme v rodičovské komponentě.
Potřebujeme tedy nástroj, který nám umožní předávat data z rodičovských do dceřiných komponent. Tímto nástrojem ve Vue jsou tzv. props.
Upravme skript komponenty CalculatorButton
takto:
export default { name: 'CalculatorButton', props: [ 'displayValue' ] }
A jediný řádek její šablony takto:
<div class="calculator-button">{{ displayValue }}</div>
Tímto jsme vytvořili proměnnou v rámci props, ve které budeme
komponentě předávat potřebná data. V našem případě tedy znak, jenž má
být zobrazen na tlačítku. Hodnotu displayValue
potom zobrazujeme
v šabloně.
V komponentě TheLayout
nyní upravme 6. řádek šablony (hned
pod elementem s třídou display
):
<calculator-button display-value="F"/>
Kalkulačka nám nyní na svém jediném tlačítku namísto písmene "C" zobrazuje "F".
Všimněme si, že:
- props jsou definovány jako pole obsahující textové řetězce - názvy jednotlivých proměnných. Props mohou být také definovány jako objekt, o tom o kousek později v této lekci.
- názvy proměnných v definici props píšeme v camelCase, tzv. velbloudíZápis.
- v rodičovské komponentě použijeme název proměnné jako HTML atribut a
rovnou mu přiřazujeme hodnotu. Takto můžeme postupovat, přiřazujeme-li
prostý textový řetězec. Chceme-li dceřiné komponentě v rámci props
předat jiná data než prostý text, anebo hodnotu nějaké proměnné, je
třeba použít direktivu
v-bind
. - HTML kód nerozpoznává v názvech atributů velká a malá písmena, proto v rodičovské komponentě píšeme název patřičné proměnné props v notaci kebab-case. Překlad těchto dvou různých notací pro nás automaticky obstará Vue.
Direktiva v-bind
Direktiva v-bind
nám umožňuje nastavit hodnotu HTML atributů
dynamicky. Uveďme si několik příkladů:
<button v-bind:type="buttonType"></button> <my-vue-component v-bind:important-value="100" v-bind:another-value="value"/> <my-vue-component v-bind:greetings="['ahoj', 'čau']" v-bind:is-valid="false" />
První řádek kódu nám nastavuje hodnotu atributu type
elementu <button>
podle hodnoty proměnné
buttonType
. Obsahuje-li tato proměnná například text
"button"
, bude první řádek odpovídat zápisu:
<button type="button"></button>
Na druhém řádku přiřazujeme do proměnné importantValue
,
která je součástí props v komponentě MyVueComponent
,
číselnou hodnotu 100
(nikoliv string '100'
) a do
další části props s názvem anotherValue
přiřazujeme obsah
proměnné value
.
Na třetím řádku přiřazujeme do proměnné greetings
,
která je součástí props v komponentě MyVueComponent
, pole
obsahující dva textové řetězce. Do další proměnné isValid
přiřazuje booleanovskou hodnotu false
.
Direktivu v-bind
je možné psát i zkratkou, kterou je pouhá
dvojtečka :
. Namísto v-bind:is-valid="false"
můžeme tedy zkráceně psát pouze :is-valid="false"
, oba zápisy
jsou ekvivalentní. V dalším kódování se budeme držet zkráceného
zápisu.
Objekt props - kontrola datových typů a validace
Zatím jsme definovali props jako pouhé pole obsahující názvy jednotlivých proměnných. Props však můžeme definovat též jako objekt, například:
props: { greeting: { type: String, default: 'ahoj' } }
V kódu výše jsme definovali prop
s názvem
greeting
. Určili jsme, že musí jít o datový typ
String
. Pokud rodičovská komponenta nepřiřadí do této
prop
žádnou hodnotu, nastaví se základní hodnota, kterou bude
textový řetězec "ahoj"
.
Kontrola datových typů může být velice užitečná zejména v
rozsáhlejších aplikacích, kdy tak získáváme kontrolu nad tím, jaká data
nám rodičovské komponenty do dceřiných předávají. Hodnota vlastnosti
type
může mít hodnotu názvu jednoho z nativních konstruktorů
v JavaScriptu (String
, Number
, Boolean
,
Array
, Object
, Date
,
Function
, Symbol
). Je-li pak předávána komponentě
hodnota, která neodpovídá datovému typu, Vue nám zobrazí na konzoli
varovné hlášení.
V případech, kdy nám prostá kontrola datového typu nestačí, můžeme v
props definovat přesnější validátor. Validátorem je funkce, která si bere
jako parametr validovanou hodnotu a vrací true
nebo
false
. Vrátí-li false
, pak Vue opět zobrazuje
chybové hlášení. Příklad:
props: { greeting: { validator: (v) => v === null || typeof v === 'string', default: null } }
Takto definujeme prop
s názvem greeting
, která
může obsahovat buď textový řetězec nebo hodnotu null
. Jiné
hodnoty přípustné nejsou. Pokud rodičovská komponenta hodnotu nenastaví,
výchozí hodnotou bude null
.
Dalším velice praktickým nastavením u props je vlastnost
required
:
props: { displayValue: { type: String, required: true } }
Kódem výše definujeme prop displayValue
, která musí
obsahovat textový řetězec a její hodnota je povinná -
musí být rodičovskou komponentou nastavena. Kdybychom ji nastavit opomněli,
opět nás nemine varovná hláška na konzoli.
Vrátíme-li se k naší kalkulačce, pak zjistíme, že výše uvedené
nastavení je přesně to, které pro zobrazovanou hodnotu tlačítka
potřebujeme. Musí to být String
, je to povinná hodnota a
nemůžeme zadat žádnou hodnotu výchozí. Použijeme tedy výše uvedený
kód v definici props komponenty CalculatorButton
, jejíž skript
teď bude vypadat takto:
export default { name: 'CalculatorButton', props: { displayValue: { type: String, required: true } } }
Pro dnešní lekci by to už stačilo
V další lekci, Podmínky a cykly ve Vue, se seznámíme s direktivami v-for
,
v-if
, v-else
, v-else-if
a naučíme se s
jejich pomocí zobrazovat HTML elementy a Vue komponenty podmíněně,
respektive v cyklech.
Měl jsi s čímkoli problém? Zdrojový kód vzorové aplikace je ke stažení každých pár lekcí. Zatím pokračuj dál, a pak si svou aplikaci porovnej se vzorem a snadno oprav.