Aktuálně: Postihly zákazy tvou profesi? Poptávka po ajťácích prudce roste, využij slevové akce 50% výuky zdarma!
Pouze tento týden sleva až 80 % na e-learning týkající se Javy

Lekce 4 - Podmínky a cykly ve Vue.js Nové

V minulé lekci, Data a props v komponentách ve Vue.js, jsme se naučili pracovat s daty uvnitř Vue komponenty a předávat data do jednotlivých komponent prostřednictvím props. Také jsme se seznámili s možností validovat props a mít tak pod kontrolou datové typy.

Připomeňme si nejdříve finální vzhled naší kalkulačky, kterého chceme dosáhnout.

Renderování v cyklech

V tuto chvíli máme hotový první řádek, zbývají nám tedy 4 řádky:

Všimněme si, co mají společného - všechny obsahují právě 4 tlačítka. V komponentě TheLayout jsme tyto řádky prozatím nahradili obyčejným elementem <div>. Je na čase vytvořit si komponentu, která nám bude reprezentovat právě jeden takovýto řádek se čtyřmi kalkulačkovými tlačítky.

V adresáři src/components vytvoříme nový soubor s názvem CalculatorRow.vue a napíšeme do něj tento kód:

<template>
  <div class="calculator-row">
    <calculator-button v-for="button of buttons" :key="button" :display-value="button"/>
  </div>
</template>
<script>
export default {
  name: 'CalculatorRow',
  props: {
    buttons: {
      required: true,
      validator: (v) => Array.isArray(v) && v.length === 4 && new Set(v).size === 4
    }
  },
}
</script>

Nejprve si vysvětleme props ve skriptu. Komponenta bude požadovat povinnou prop s názvem buttons. Ve validační funkci ověříme, že hodnota má datový typ pole. Dále ověříme, že toto pole obsahuje právě 4 prvky. Nakonec ověříme skutečnost, že všechny prvky v poli mají unikátní hodnotu (v řádku se nemohou opakovat dvě stejná tlačítka). Touto validační funkcí navazujeme na předchozí lekci a připomínáme si užití validace props v komponentách.

Například druhý řádek kalkulačky bude obsahovat tlačítka 7, 8, 9 a /. Komponenta CalculatorRow, která bude tento řádek představovat, bude muset dostat do své prop buttons toto pole: ['7', '8', '9', '/'].

Nyní k šabloně. Je tvořena obalujícím elementem <div> s CSS třídou .calculator-row. Připomínám, že tato třída je již deklarována ve stylech komponenty TheLayout, není třeba ji tedy znovu deklarovat zde. CSS deklarace jsou ve Vue globální, pokud toto nastavení nezměníme, ale o tom později.

Obalový element <div> obsahuje komponentu CalculatorButton. Připomeňme si, že jsme ji registrovali v druhé lekci globálně, o její registraci se tedy v tuto chvíli už starat nemusíme.

V zápisu této komponenty v šabloně si všimněme direktivy v-for. Jde o direktivu, která nám umožňuje cyklické renderování podle prvků pole. Kód v-for="button of buttons" prochází pole buttons, které máme definované v props. Při každé této iteraci se vytvoří jedna instance komponenty CalculatorButton. Tímto kódem jsme si též vytvořili proměnnou button, která obsahuje právě iterovaný prvek pole buttons. Proměnou používáme hned v téže komponentě - přiřazujeme pomocí direktivy v-bind hodnotu proměnné button do prop s názvem displayValue komponenty CalculatorButton. Do tlačítka tak dostáváme právě ten znak, který na něm má být zobrazen.

Tento výukový obsah pomáhají rozvíjet následující firmy, které dost možná hledají právě tebe!

Dále si všimněme direktivy v-key, která je v kódu zapsána zkratkou :key (oba zápisy v-key a :key jsou ekvivalentní). Při renderování v cyklech je třeba, aby každá zobrazovaná komponenta měla k sobě přiřazen unikátní klíč, pomocí kterého ji Vue bude moci identifikovat. Toto přiřazení klíče je syntaktickou podmínkou frameworku Vue 3. V naší kalkulačce si můžeme být jisti, že každé tlačítko bude obsahovat jiný znak. Hodnota proměnné button tedy bude jedinečná a můžeme ji přímo použít jako klíč.

Podrobněji o direktivě v-for

Následující příklady s naší kalkulačkou přímo nesouvisí, můžete si je ale vyzkoušet v kterékoliv již existující zobrazované komponentě, anebo si pro ně vytvořit komponentu novou.

Renderování cyklů můžeme použít na kterékoliv Vue komponentě, stejně tak ale i na libovolném HTML elementu. Například kód:

<template>
  <div v-for="greeting of ['ahoj', 'čau']" :key="greeting" >{{ greeting }}</div>
</template>

nám zobrazí dva elementy <div>, první s textem "ahoj", druhý s textem "čau".

Pro úplnost ještě dodejme, že kromě právě iterovaného prvku pole můžeme zobrazované komponentě (anebo HTML elementu) předat také index (pořadí prvku v poli počítané od nuly).

Když si předchozí kód upravíme takto:

<template>
  <div v-for="(greeting, index) of ['ahoj', 'čau']" :key="greeting" >{{ (index + 1) + '. pozdrav:' + greeting }}</div>
</template>

zobrazí se vám dva elementy <div>, které budou obsahovat texty "1. pozdrav: ahoj" a "2. pozdrav: čau".

Vnoření cyklů

Vraťme se zpět k naší kalkulačce. Máme vytvořenou komponentu CalculatorRow, zatím ji však nikde nezobrazujeme. Zobrazíme ji v naší hlavní komponentě TheLayout a to dokonce 4x, protože naše kalkulačka bude mít celkem 4 řádky. Upravme skript komponenty TheLayout takto:

import CalculatorRow from '@/components/CalculatorRow.vue'
export default {
  name: 'TheLayout',
  data () {
    return {
      value: '0',
      rows: [
        ['7', '8', '9', '/'],
        ['4', '5', '6', 'X'],
        ['1', '2', '3', '-'],
        ['0', ',', '=', '+']
      ]
    }
  },
  components: { CalculatorRow }
}

Tím jsme v datech této komponenty vytvořili dvourozměrné pole rows. Jeho prvky jsou pole obsahující znaky tlačítek na jednotlivých řádcích kalkulačky. Nyní už nám nic nebrání použít komponentu CalculatorRow v cyklu. Šablonu TheLayout tedy upravíme takto:

<template>
  <div class="container">
    <div class="calculator">
      <div class="calculator-row">
        <div class="display"></div>
        <calculator-button display-value="C"/>
      </div>
      <calculator-row
         v-for="(row, index) of rows"
        :key="'row' + (index + 1)"
        :buttons="row"/>
    </div>
  </div>
</template>

Nyní vidíme, že jsme pod prvním řádkem kalkulačky zobrazili 4 další řádky, a to cyklickým použitím komponenty CalculatorRow. Ta sama již v sobě obsahuje cyklus pro zobrazování jednotlivých tlačítek, náš kód je tedy příkladem toho, jak je možné zobrazovat cykly navzájem vnořené do sebe.

Podobně by mohlo být nakódováno vnoření dvou cyklů jen v jediné komponentě - direktiva v-for může být neomezeně zanořována. Všimněme si také, že pole znaků, které mají být zobrazeny v jednotlivých řádcích kalkulačky, předáváme direktivou v-bind do prop buttons každé instance komponenty CalculatorRow.

Unikátní klíč každé instance této komponenty nyní tvoříme pomocí stringu "row" a indexu. Klíče budou mít hodnoty "row1", "row2", atd., čímž je zajištěna jejich jedinečnost v celém HTML dokumentu.

V prohlížeči nyní uvidíme kalkulačku v této podobě:

Podmíněné renderování - direktivy v-if, v-else-if, v-else

Direktiva v-if musí obsahovat JavaScriptový výraz a komponenta, resp. HTML element direktivu obsahující se zobrazí jen tehdy, je-li výsledek výrazu pravdivý (truthy).

Podobně funguje direktiva v-else-if, musí však být řazena v pořadí za v-if a její výraz se vyhodnocuje pouze tehdy, není-li splněna podmínka předchozí v-if.

Direktiva v-else již žádný výraz neobsahuje a musí být řazena za direktivu v-if, respektive v-else-if. Element, který ji obsahuje, je zobrazen pouze tehdy, není-li splněna žádná z podmínek předchozích direktiv.

Je třeba připomenout, že zobrazovaní elementů pomocí těchto direktiv je absolutní, nejde tedy o pouhé skrývání či odkrývání elementů pomocí CSS stylů (např. display: none nebo visibility: hidden). Elementy, u kterých tyto direktivy určí, že nemají být zobrazeny, zkrátka nejsou ve výsledném HTML dokumentu vůbec obsaženy.

Abychom si vyzkoušeli podmíněné renderování, odlišíme graficky pozadí tlačítka, které obsahuje písmeno "C" od ostatních tlačítek kalkulačky. Upravme kód komponenty CalculatorButton takto:

<template>
  <div
    v-if="displayValue === 'C'"
    class="calculator-button calculator-button-operator">
    {{ displayValue }}
  </div>
  <div
    v-else
    class="calculator-button">
    {{ displayValue }}
  </div>
</template>

<script>
export default {
  name: 'CalculatorButton',
  props: {
    displayValue: {
      type: String,
      required: true
    }
  }
}
</script>

<style scoped>
.calculator-button {
  display: flex;
  justify-content: center;
  align-items: center;
  padding: .75em;
  font-size: 1.5rem;
  font-weight: bold;
  flex: 0 0 auto;
  width: 60px;
  cursor: pointer;
  transition: all .3s ease-in-out;
}
.calculator-button:not(.calculator-button-operator) {
  background: transparent
}
.calculator-button:not(.calculator-button-operator):hover {
  background: #F2EDCF;
}
.calculator-button:active {
  transform: scale(.85);
  box-shadow: 0px 0px 0px 1px rgba(0, 0, 0, .15)
}
.calculator-button-operator {
  background: #fee8d7;
}
.calculator-button-operator:hover {
  background: #FDDDC3;
}
</style>

Ve webovém prohlížeči nyní vidíme, že tlačítko "C" má tmavší barvu pozadí než ostatní:

Komponenta zobrazuje vždy jeden ze dvou elementů <div>, které jsou nakódovány v šabloně, a to podle vyhodnocení podmínky obsažené v direktivě v-if.

V další lekci, Computed properties a dynamické styly ve Vue.js, se seznámíme s tzv. computed properties a naučíme se stylovat komponenty a HTML elementy dynamicky.


 

Měl jsi s čímkoli problém? Stáhni si vzorovou aplikaci níže a porovnej ji se svým projektem, chybu tak snadno najdeš.

Stáhnout

Stažením následujícího souboru souhlasíš s licenčními podmínkami

Staženo 4x (35.3 MB)
Aplikace je včetně zdrojových kódů v jazyce JavaScript

 

Předchozí článek
Data a props v komponentách ve Vue.js
Všechny články v sekci
Vue.js
Článek pro vás napsal Tomáš Glabazňa
Avatar
Jak se ti líbí článek?
1 hlasů
Aktivity (5)

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!