Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

Lekce 4 - Podmínky a cykly ve Vue

V minulé lekci, Data a props v komponentách ve Vue, 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.

V této lekci Vue tutoriálu budeme pokračovat v tvorbě kalkulačky. Podíváme se blíže na podmínky a cykly. Připomeňme si nejdříve finální vzhled, kterého s naší kalkulačkou chceme dosáhnout.

Vue

Renderování v cyklech

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

Vue

Všimněme si, co mají společného - všechny obsahují právě čtyři 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ý řá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ě čtyři 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.

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

Pokud pole validační kritéria nesplní, například bude obsahovat 2x tlačítko 7: ['7', '7', '9', '/'], objeví se po spuštění stránky v konzoli prohlížeče varování:

Vue

Nyní k šabloně. Ta je tvořena obalujícím elementem <div> s CSS třídou .calculator-row. Tato třída je již deklarována ve stylech komponenty TheLayout a není tedy třeba ji 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ě. Pomocí direktivy v-bind přiřazujeme 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.

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ě, případně 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).

Předchozí kód nyní upravíme takto:

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

Tím se zobrazí 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 čtyřikrát, protože naše kalkulačka bude mít celkem čtyři řádky. Upravíme si 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 čtyři 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ě, protože 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ě:

Vue

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 proto 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í:

Vue

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, 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 42x (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
Všechny články v sekci
Vue
Přeskočit článek
(nedoporučujeme)
Computed properties a dynamické styly ve Vue
Článek pro vás napsal Tomáš Glabazňa
Avatar
Uživatelské hodnocení:
33 hlasů
Aktivity