IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

5. diel - Computed properties a dynamické štýly vo Vue.js

V predchádzajúcej lekcii, Podmienky a cykly vo Vue.js , sme sa naučili zobrazovať HTML elementy alebo Vue komponenty podmienečne a v cykloch. Zoznámili sme sa s direktívami v-for, v-if, v-else a v-else-if.

Dnes si ukážeme špecifické použitie direktívy v-bind pre atribúty class a style, computed properties, princíp reaktivity

Computed properties

Vue komponenty vo väčšine prípadov obsahujú dáta. Niektoré z nich sú definované priamo v kóde danej komponenty (spomeňme na vlastnosť data konfiguračného objektu), iná sú komponente odovzdávaná z rodičovskej komponenty prostredníctvom Props.

Medzi týmito dvoma dátovými zdrojmi je jeden zásadný rozdiel. Kým data môžu svoje hodnoty rôzne meniť (najčastejšie k tomu dochádza v metódach konfiguračného objektu, o ktorých bude reč neskôr), hodnoty Props sú vo vnútri komponenty nemenné. Ak by sme sa kdekoľvek v kóde pokúsili o zmenu hodnoty niektoré z Props, Vue zobrazí na konzole chybové hlásenie a kód nebude fungovať.

Ak potrebujeme niektorú hodnotu z Props meniť, respektíve ju použiť k ďalším výpočtom, oceníme iste ďalší nástroj, ktorý nám framework Vue ponúka - computed properties. Ide o ďalší vlastnosť konfiguračného objektu s názvom computed. Jej obsahom musí byť objekt obsahujúci iba metódy. Každá táto metóda musí povinne vracať hodnotu a môže pracovať s dátami alebo Props danej komponenty. K nim pristupuje pomocou this, ktoré v tomto prípade referuje samotnú komponent. Zápis this.something teda odkazuje na dátovú hodnotu danej komponenty s názvom something, či už bola definovaná v Props, v dátach, alebo v computed properties.

Z toho logicky vyplýva ďalšie pravidlo. Názvy jednotlivých premenných musí byť unikátne v celej komponente, názov, ktorý bol použitý napríklad v Props, už nejde druhýkrát použiť v dátach ani v computed properties pod.

Ukážme si fungovanie computed properties na jednoduchom príklade:

<template>
  <div>{{ fullName }}</div>
</template>
<script>
export default {
  name: 'FullName',
  props: {
    firstName: { required: true, type: String },
    lastName: { required: true, type: String }
  },
  computed: {
    fullName () {
      return this.firstName + ' ' + this.lastName
    }
  }
}
</script>

Tento komponent dostáva od svojej rodičovskej komponenty dve hodnoty v Props: firstName a lastName. V computed properties je potom definovaná nová hodnota - fullName ako výpočet z oboch predchádzajúcich. Tá je potom zobrazovaná v šablóne. Komponent by sme mohli použiť napríklad takto:

<template>
  <div>
    <full-name first-name="Honza" last-name="Novák"/>
    <full-name first-name="Pepa" last-name="Horák"/>
  </div>
</template>
<script>
import FullName from '@/components/FullName.vue'
export default {
 components: { FullName }
}
</script>

Tento kód by zobrazil dve celé mená - "Honza Novák" a "Pepa Horák".

Príklad sa vám iste môže zdať triviálne, zmysel využitie computed properties však rastie s náročnosťou výpočtu či aplikačnej logiky. Je tiež dôležité vziať do úvahy, že hodnoty computed properties sú automaticky prepočítané zakaždým, keď sa zmení niektorá vstupná hodnota pre ich výpočet. Keď uvážime, že hodnoty môžu byť odovzdávané z rodičovských do dcérskych komponentov dynamicky, potom je zrejmé, že nám computed properties výrazne uľahčujú prácu.

Direktíva v-bind:class

Pripomeňme si, že direktíva v-bind priraďuje hodnotu obsiahnutého JavaScriptového výrazu, ktorý môže obsahovať premenné danej komponenty, do Props komponenty dcérskej alebo priamo do atribútu HTML elementu. Medzi HTML atribúty však existujú dve výnimky, kedy je potrebné použiť odlišnú syntax - atribúty class a style. Vue nám umožňuje dynamicky priraďovať CSS triedy do atribútu class dvoma spôsobmi:

Objektová syntaxe

V objekte, ktorý je priradený direktíve v-bind, definujeme CSS triedy ako názvy jednotlivých vlastností. Hodnoty týchto vlastností sú JavaScriptové výrazy, ktoré sa po vyhodnotení ako pravdivé (Truth), je trieda danému elementu priradená, v opačnom prípade nie.

<div :class="
  { 'class-name': condition,
  { 'another-class': anotherCondition }
">
</div>

Vyššie uvedeným kódom priraďujeme jednotlivé CSS triedy elementu <div> podmienečne. Ak je výraz condition pravdivý, bude classList elementu div obsahovať CSS triedu .class-name. Ďalej, ak je pravdivý výraz anotherCondition, bude classList elementu obsahovať CSS triedu .another-class.

Array syntaxe

Direktíve v-bind na atribútu class môžeme okrem objektu priradiť aj pole obsahujúce stringy - názvy jednotlivých CSS tried:

<div :class="['red-border', 'light-shadow', className]"></div>

Kód vyššie priradí elementu <div> CSS triedy .red-border, .light-shadow a potom ešte tú triedu, ktorej názov je obsiahnutý v premennej className.

Ak potrebujeme v array syntaxi použiť podmienky, je to pomerne jednoduché. Namiesto textového reťazca môže byť prvkom poľa objekt s jednou vlastnosťou (názov triedy) a jej hodnotou (výraz - podmienka):

<div :class="['light-shadow', { 'red-border': !isValid }]"></div>

Takto napríklad priradíme elementu <div> CSS triedu "light-shadow" vždy a triedu "red-border" práve vtedy, keď hodnota premennej isValid bude nepravdivá (false).

V príkladoch oboch syntaxou sme objekty / pole vypisovali priamo do šablóny. Pomerne často je však využívaná technika, kedy sú objekty / polia vypočítané v skripte, a to najčastejšie práve v computed properties, o ktorých sme hovorili na začiatku lekcie.

Direktíva v-bind:style

Druhou výnimkou zo všeobecnej syntaxe direktívy v-bind je atribút style, ktorým sú HTML elementu priraďované inline CSS štýly.

Objektová syntaxe

Názvy CSS vlastností píšeme ako názvy vlastností objektu. Môžeme tu však vedľa notácie kebab-case písané v jednoduchých úvodzovkách použiť aj notáciu CamelCase. Zápisy 'border-top-color' a borderTopColor sú teda ekvivalentné. Tieto vlastnosti štýlového objektu potom obsahujú požadované hodnoty CSS vlastností (samozrejme vrátane jednotiek):

<div :style="{fontSize: size + 'px'}"></div>

Kód vyššie tak teda napríklad definuje v elemente <div> výšku písma (font-size) práve toľko pixelov, koľko je hodnota premennej size. Nedáva Ak výraz size + 'px' platnú CSS hodnotu, bude tento zápis ignorovaný.

Array syntaxe

Podobne ako u v-bind:class bývajú štýlové objekty definované v skripte, a to najčastejšie v computed properties. Array syntaxe nám umožňuje zlúčiť štýly niekoľkých štýlových objektov dohromady, napríklad takto:

<div :style="[styleObject1, styleObject2]"></div>

Kalkulačka - štýlovanie tlačidiel

Teóriu vysvetlenú vyššie teraz uplatníme v našej kalkulačke. Po minulej lekcii, kde sme si potrebovali ukázať podmienenej renderovanie, obsahuje naša komponenta CalculatorButton vo svojej šablóne opakovaný kód. Opisujú tu dvakrát ten istý element <div>, jeho jednotlivé opakovania sa líšia iba CSS triedou .calculator-button-operator, ktorá v prvom výskyte obsiahnutá nie je, v druhom áno. Pomerne nešikovne potom na základe podmienky v direktíve v-if zobrazujeme buď prvý alebo druhý element <div>.

Iste by bolo praktickejšie, rovnako tak náš kód by bol lepšie čitateľný a udržiavateľný, keby sme vždy zobrazovali len jeden element <div> a vyhodnotenie podmienky by rozhodovalo iba o priradenie danej CSS triedy.

Ďalej chceme, aby tmavšie oranžové pozadia mala všetky tlačidlá okrem položiek a desatinnej čiarky. Tieto tlačidlá budeme pracovne nazývať "operátormi".

Upravme šablónu a skript komponenty CalculatorButton takto:

<template>
  <div
    class="calculator-button"
    :class="{ 'calculator-button-operator': isOperator }"
  >
  {{ displayValue }}
  </div>
</template>
<script>
export default {
  name: 'CalculatorButton',
  props: {
    displayValue: {
      type: String,
      required: true
    }
  },
  computed: {
    isOperator () {
      return this.displayValue !== ',' && isNaN(parseInt(this.displayValue))
    }
  }
}
</script>

Vo scriptu sme vytvorili jednu dátovú položku v computed properties. Jej názov je isOperator a ide o funkciu, ktorá vracia hodnotu false pre tlačidlá zobrazujúci číslo alebo desatinnú čiarku, hodnotu true potom vracia pre všetky ostatné tlačidlá.

V šablóne sme použili štandardné atribút class elementu <div>, v ktorom tomuto elementu priraďujeme CSS triedu .calculator-button. Táto trieda je teda priradená vždy, v každom tlačidle bez rozdielu. V tom istom elementu sme ďalej použili direktívu :class a priradili jej objekt s jedinou vlastnosťou. Takto bude trieda .calculator-button-operator elementu priradená práve vtedy, keď funkcia isOperator vráti true.

Všimnime si, že Vue umožňuje v jedinom elementu použiť oboje - štandardný atribút class spolu s direktívou :class. Danému elementu sa v takomto prípade priradí všetky CSS triedy definované jedným aj druhým spôsobom dohromady. U atribútu style direktívy :style to funguje obdobne.

Naša kalkulačka teraz vyzerá takto:

Vue.js

V ďalšej lekcii sa budeme venovať udalostiam vo Vue. Predstavíme si direktívu v-on a naučíme sa odovzdávať dáta z dcérskych do rodičovských komponentov emitovaním vlastných udalostí.


 

Predchádzajúci článok
Podmienky a cykly vo Vue.js
Všetky články v sekcii
Vue.js
Preskočiť článok
(neodporúčame)
Udalosti vo Vue.js
Článok pre vás napísal Tomáš Glabazňa
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
Aktivity