Условный рендеринг

v-if

В строковых шаблонизаторах, например в Handlebars, мы бы определили условно отображаемый блок так:

<!-- шаблон Handlebars -->
{{#if ok}}
<h1>Да</h1>
{{/if}}

Во Vue для тех же целей применяется директива v-if:

<h1 v-if="ok">Да</h1>

Также можно добавить блок “иначе”, используя v-else:

<h1 v-if="ok">Да</h1>
<h1 v-else>Нет</h1>

Условные группы с использованием v-if и <template>

Поскольку v-if — это директива, она должна быть указана в одном конкретном теге. А что если мы хотим управлять отображением сразу нескольких элементов? В этом случае мы можем применить v-if к псевдоэлементу <template>, который служит невидимой обёрткой, и сам в результатах рендеринга не появляется.

<template v-if="ok">
<h1>Заголовок</h1>
<p>Абзац 1</p>
<p>Абзац 2</p>
</template>

v-else

Для указания блока “иначе” для v-if можно использовать директиву v-else:

<div v-if="Math.random() > 0.5">
Сейчас меня видно
</div>
<div v-else>
А теперь — нет
</div>

Элемент с директивой v-else должен следовать непосредственно за элементом с директивой v-if или v-else-if, иначе он не будет опознан.

v-else-if

Добавлено в версии 2.1.0

Как следует из названия, v-else-if служит в качестве “блока else if” для директивы v-if. Можно объединять эти директивы в длинные цепочки:

<div v-if="type === 'A'">
A
</div>
<div v-else-if="type === 'B'">
B
</div>
<div v-else-if="type === 'C'">
C
</div>
<div v-else>
Не A/B/C
</div>

Подобно v-else, v-else-if должен непосредственно следовать за элементом с v-if или v-else-if.

Управление повторным использованием элементов при помощи key

Vue старается рендерить элементы DOM настолько эффективно, насколько это возможно, зачастую переиспользуя их вместо того чтобы создавать заново. Помимо улучшения производительности, в этом подходе можно обнаружить и иные преимущества. Например, если вы позволяете пользователю переключаться между несколькими возможными типами логина:

<template v-if="loginType === 'username'">
<label>Имя пользователя</label>
<input placeholder="Введите имя пользователя">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Введите адрес email">
</template>

Переключение loginType в коде выше не сотрёт то, что пользователь уже ввёл. Оба шаблона используют одни и те же элементы, поэтому <input> не заменяется — только его placeholder.

Попробуйте сами, сначала введя что-нибудь в input, а затем нажав на кнопку переключения:

Надо сказать, что это поведение может не всегда быть тем, что нужно. Поэтому Vue позволяет явно сказать: “эти элементы должны быть полностью независимы: не надо их переиспользовать”. Для этого нужно всего лишь указать уникальное значение ключа key:

<template v-if="loginType === 'username'">
<label>Имя пользователя</label>
<input placeholder="Введите имя пользователя" key="username-input">
</template>
<template v-else>
<label>Email</label>
<input placeholder="Введите адрес email" key="email-input">
</template>

Теперь эти input’ы будут рендериться заново при каждом переключении. Смотрите сами:

Обратите внимание, что элементы <label> всё так же эффективно переиспользуются, поскольку для них key не указаны.

v-show

Ещё одну возможность условного отображения даёт директива v-show. Используется она так же:

<h1 v-show="ok">Привет!</h1>

Разница состоит в том, что элемент с v-show будет всегда оставаться в DOM, а изменяться будет лишь свойство display в его параметрах CSS.

Обратите внимание, что v-show не поддерживает использование <template> и не работает с v-else.

v-if vs v-show

v-if производит “настоящий” условный рендеринг, удостоверяясь что подписчики событий и дочерние компоненты внутри блока должным образом уничтожаются и воссоздаются при изменении истинности управляющего условия.

v-if также ленив: если условие ложно на момент первоначального рендеринга, он не произведёт никаких действий — условный блок не будет отображён, пока условие впервые не станет истинным.

v-show, напротив, куда проще: элемент всегда присутствует в DOM, и только CSS-свойство переключается в зависимости от значения выражения.

В целом у v-if выше стоимость переключения, а у v-show выше стоимость первичного рендеринга. Так что если вы предполагаете, что переключения будут частыми, используйте v-show, если же редкими или вовсе маловероятными — v-if.

v-if вместе с v-for

При совместном использовании v-if и v-for, v-for имеет более высокий приоритет. Подробности на странице рендеринга списков.