Циклы
Цикл повторяет кусок разметки для каждого элемента данных. Меню кофейни из двадцати напитков не нужно копировать вручную — достаточно массива и одного each.
each по массиву
Простой список напитков в src/index.pug:
- const drinks = ["Эспрессо", "Капучино", "Какао"]
ul
each drink in drinks
li= drinkСтроки под each повторяются для каждого элемента, а переменная drink по очереди принимает значения из массива:
<ul>
<li>Эспрессо</li>
<li>Капучино</li>
<li>Какао</li>
</ul>Номер элемента
Вторая переменная после запятой получает номер элемента, начиная с нуля:
- const drinks = ["Эспрессо", "Капучино", "Какао"]
each drink, index in drinks
p #{index + 1}. #{drink}Чтобы нумерация начиналась с единицы, к номеру прибавляется 1:
<p>1. Эспрессо</p>
<p>2. Капучино</p>
<p>3. Какао</p>Меню из данных
В реальном проекте список приходит из скрипта сборки. Передайте массив объектов в build.js:
// build.js
const menu = [
{ name: "Эспрессо", price: 2 },
{ name: "Капучино", price: 3 },
{ name: "Какао", price: 3, soldOut: true },
];
const html = pug.renderFile("src/index.pug", { pretty: true, menu });В src/index.pug у каждого элемента берутся свойства через точку, а закончившийся напиток получает класс:
ul.menu
each item in menu
li(class=item.soldOut ? "sold-out" : undefined)
span.name= item.name
span.price $#{item.price}Три пункта меню, у какао класс sold-out, которым в CSS можно сделать текст серым:
<ul class="menu">
<li><span class="name">Эспрессо</span><span class="price">$2</span></li>
<li><span class="name">Капучино</span><span class="price">$3</span></li>
<li class="sold-out"><span class="name">Какао</span><span class="price">$3</span></li>
</ul>each по объекту
Если перебирать объект, первая переменная получает значение, вторая — ключ:
- const hours = { "Будни": "8:00–20:00", "Выходные": "10:00–18:00" }
dl
each time, days in hours
dt= days
dd= timeПорядок переменных обратный привычному: сначала значение, потом ключ:
<dl>
<dt>Будни</dt>
<dd>8:00–20:00</dd>
<dt>Выходные</dt>
<dd>10:00–18:00</dd>
</dl>Пустой список
Ветка else под each выводится, когда в массиве нет элементов:
- const desserts = []
ul
each dessert in desserts
li= dessert
else
li Десертов пока нет.Вместо пустого списка посетитель увидит сообщение:
<ul>
<li>Десертов пока нет.</li>
</ul>while
while повторяет разметку, пока условие верно. Он нужен редко — для списков удобнее each:
- let n = 1
ul
while n <= 3
li Столик №#{n++}Не забудьте менять переменную внутри цикла (здесь n++), иначе цикл никогда не закончится:
<ul>
<li>Столик №1</li>
<li>Столик №2</li>
<li>Столик №3</li>
</ul>Частая ошибка
Выводить весь объект вместо его свойства:
ul
each item in menu
li= itemJavaScript превращает объект в строку [object Object]:
<ul>
<li>[object Object]</li>
<li>[object Object]</li>
<li>[object Object]</li>
</ul>Обращайтесь к нужному свойству: item.name, item.price.