Директивы: v-if, v-for, v-bind
Директивы
Директивы — специальные атрибуты шаблона, которые начинаются с v-. Они говорят Vue, что
сделать с элементом: показать по условию, повторить для каждого элемента массива, привязать атрибут
к данным. Значение директивы — JavaScript-выражение, в котором доступно всё, что вернул setup.
v-if, v-else-if, v-else
<p v-if="score >= 90">Отлично!</p>
<p v-else-if="score >= 60">Хорошо</p>
<p v-else>Попробуй ещё</p>
Элемент с ложным v-if не создаётся вовсе (вместо него в DOM остаётся невидимый комментарий).
v-else-if и v-else должны идти сразу за элементом с v-if.
Чтобы показать по условию сразу несколько элементов без лишней обёртки, используют <template>:
<template v-if="user">
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
</template>
v-show
<div v-show="menuOpen">Меню</div>
v-show не удаляет элемент, а только прячет его через display: none. Разница: v-if дешевле при
первой загрузке (ничего не создаёт), v-show — при частом переключении (не пересоздаёт). Для
выпадающих меню и вкладок, которые часто открывают, — v-show, для редких условий — v-if.
v-for — списки
<ul>
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
v-for="item in items" повторяет элемент для каждого значения массива. Можно получить и индекс:
v-for="(item, index) in items". Перебирать можно и число: v-for="n in 5" даст 1…5.
:key — как в React: уникальный и постоянный идентификатор, по которому Vue сопоставляет элементы
при обновлении. Используй id из данных.
Отфильтровать или отсортировать список лучше в JavaScript, а в шаблоне перебирать результат:
const visible = () => items.value.filter((i) => !i.hidden);
<li v-for="item in visible()" :key="item.id">{{ item.name }}</li>
Не ставь v-if и v-for на один элемент — это путает и запрещено правилами стиля Vue.
Важно: sort() меняет массив на месте. Если отсортировать сам реактивный массив прямо в шаблоне,
изменятся данные, и Vue начнёт перерисовывать снова. Сортируй копию: [...arr].sort(...).
v-bind — атрибуты из данных
Чтобы значение атрибута бралось из данных, перед атрибутом пишут v-bind: или коротко ::
<img :src="avatarUrl" :alt="user.name" />
<a :href="`/users/${user.id}`">Профиль</a>
<button :disabled="loading">Сохранить</button>
<input :placeholder="hint" />
Без двоеточия значение — просто строка: src="avatarUrl" вставит буквально текст avatarUrl.
Классы и стили
У :class есть удобная форма — объект, где ключи — классы, а значения — условия:
<li :class="{ done: task.done, urgent: task.priority > 2 }">{{ task.text }}</li>
Класс done будет у элемента, только когда task.done истинно. Обычный class="..." и :class
можно писать вместе — Vue их объединит. Есть и форма массива: :class="[size, color]".
:style принимает объект CSS-свойств:
<div :style="{ width: progress + '%', backgroundColor: color }"></div>
Итог
v-if / v-else-if / v-else— создать или нет;v-show— спрятать стилем.v-for="x in list"с:key— списки; сортируем и фильтруем копию в JS.:атрибут="выражение"— привязка;:class="{ класс: условие }"— классы по условию.