Vue
Синтаксис шаблонов и директивы
Разработчик пришёл из React и открывает первый шаблон Vue. Вместо JSX тут почти обычный HTML, но с непривычными атрибутами: двоеточие перед именем, собака перед событием, странное v-for. Первая реакция - это какой-то отдельный язык. На деле это набор из десятка директив, и большинство кода в реальном приложении укладывается в пять из них. Понимание этих пяти закрывает девяносто процентов повседневной работы с шаблонами.
- Любой список товаров, сообщений или задач в интерфейсе рендерится через v-for с уникальным key
- Кнопки, формы и модальные окна показываются и прячутся через v-if и v-show в зависимости от состояния
- Привязка класса и стиля через v-bind это основа любой темизации и подсветки активного элемента
- Обработка кликов, ввода и отправки форм идёт через v-on, чаще в краткой записи через собаку
- Модификаторы вроде prevent и stop убирают рутинный код вызова preventDefault и stopPropagation вручную
Предварительные знания
- Понимание формата SFC и блока template из урока vue-03
- HTML: атрибуты, элементы форм, события DOM на уровне идеи
- JavaScript-выражения: тернарный оператор, обращение к свойствам, методы массивов
- Базовое представление о реактивных переменных через ref
Интерполяция, v-bind и v-on
Самый базовый способ показать данные это интерполяция: двойные фигурные скобки в тексте подставляют результат JavaScript-выражения. Внутри можно писать не только имя переменной, но и любое одиночное выражение: арифметику, вызов метода, тернарный оператор. Значение пересчитывается автоматически при изменении реактивного состояния.
Двойные фигурные скобки работают только в тексте. Чтобы привязать значение к атрибуту HTML, нужна директива v-bind, у которой есть краткая запись через двоеточие: :src означает v-bind:src. Для событий есть директива v-on с краткой записью через собаку: @click означает v-on:click. Эти две краткие формы встречаются в шаблонах постоянно.
| Полная запись | Краткая | Назначение |
|---|---|---|
| v-bind:src | :src | Привязать атрибут к выражению |
| v-on:click | @click | Навесить обработчик события |
| v-bind:class | :class | Динамически задать классы |
В шаблоне допустимо одиночное выражение, а не любой код. Можно написать тернарный оператор или вызов метода, но не объявление переменной, не if-блок и не цикл. Если логика разрастается, её выносят в computed из отдельного урока.
Зачем нужна директива v-bind, если есть интерполяция через двойные фигурные скобки?
v-if против v-show
Vue даёт два способа условно отображать элемент. Директива v-if при ложном условии полностью убирает элемент из DOM: его там просто нет. Директива v-show всегда оставляет элемент в DOM, но при ложном условии прячет его через CSS-свойство display none. Разница в том, что переключение v-if пересоздаёт элемент, а v-show только меняет видимость.
- v-if — Полностью добавляет или удаляет элемент из DOM. Дороже при частом переключении, но не рендерит элемент вообще, пока условие ложно. Поддерживает v-else и v-else-if.
- v-show — Элемент всегда в DOM, прячется через display none. Дешевле при частом переключении, но всегда занимает место в разметке. Не работает с v-else.
Практическое правило: если элемент переключается часто (например, по наведению или по табам), выгоднее v-show, потому что он не пересоздаёт узел. Если условие меняется редко или элемент тяжёлый и не нужен большую часть времени, лучше v-if, чтобы не держать лишнее в DOM.
В чём ключевое различие между v-if и v-show?
v-for с ключом и модификаторы
Директива v-for рендерит элемент для каждого пункта массива или свойства объекта. Синтаксис похож на цикл: item in items. Критически важная деталь это атрибут key с уникальным значением для каждого элемента. По ключу Vue понимает, какой узел какому элементу данных соответствует, и при переупорядочивании или удалении переиспользует существующие узлы, а не пересоздаёт всё подряд.
В примере выше видны модификаторы. Запись @submit.prevent навешивает обработчик отправки формы и автоматически вызывает preventDefault, чтобы страница не перезагружалась. Запись @keyup.enter срабатывает только на клавишу Enter. Модификаторы это суффиксы после точки, которые добавляют типовое поведение событию без ручного кода внутри обработчика.
| Модификатор | Что делает |
|---|---|
| .prevent | Вызывает event.preventDefault() |
| .stop | Вызывает event.stopPropagation() |
| .once | Срабатывает только один раз |
| .enter | Реагирует только на клавишу Enter |
Использовать индекс массива как key плохая идея, если список можно переупорядочивать, фильтровать или удалять из середины. При сдвиге индексов Vue запутается в соответствии узлов и данных, что приведёт к багам отображения. Нужен стабильный уникальный идентификатор вроде id из данных.
Почему каждому элементу v-for нужен уникальный key?
Связь с другими темами
Этот урок про язык шаблонов. Дальше разбираем, что делает их живыми:
- Основы реактивности — Директивы отслеживают реактивные значения и автоматически обновляют DOM при их изменении
- computed — Производные значения часто подставляются в интерполяцию и v-if вместо громоздких выражений в шаблоне
Итог
- Интерполяция через двойные фигурные скобки вставляет значение JavaScript-выражения в текст, и оно автоматически обновляется при изменении
- v-bind (краткая запись - двоеточие) привязывает атрибут HTML к выражению, v-on (краткая запись - собака) навешивает обработчик события
- v-if полностью убирает элемент из DOM при ложном условии, v-show оставляет его в DOM и прячет через display none
- v-for рендерит список, и каждому элементу нужен уникальный key, чтобы Vue корректно отслеживал изменения при переупорядочивании
- Модификаторы после точки (prevent, stop, enter, once) добавляют типовое поведение событиям без ручного кода в обработчике
Связанные уроки
- vue-05-reactivity-fundamentals — Директивы привязываются к реактивному состоянию, и понимание этой связи раскрывается в уроке о реактивности
- vue-03-sfc-components — Синтаксис шаблонов живёт внутри блока template файла SFC, разобранного в предыдущем уроке