Unetway

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

v-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

Директива 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-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.

Такое поведение не всегда может быть тем, что нужно. Поэтому чтобы элементы были независимы и их не нужно было переиспользовать, 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.

Директива 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 имеет более высокий приоритет.