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

Показываем и прячем части интерфейса по условию: разбираем v-if/v-else и v-show и понимаем, чем они отличаются под капотом.

v-if добавляет или удаляет элемент из DOM в зависимости от условия. v-show всегда оставляет элемент в DOM, но переключает его видимость через CSS display.

v-if, v-else-if, v-else

Директива v-if рендерит элемент, только если её условие истинно. Рядом можно поставить v-else-if и v-else — как обычная цепочка if/else:

<template>
  <p v-if="score >= 90">Отлично!</p>
  <p v-else-if="score >= 60">Неплохо</p>
  <p v-else>Нужно подтянуть</p>
</template>

<script setup>
import { ref } from 'vue'
const score = ref(75)
</script>

На экране окажется ровно один из трёх абзацев. Когда условие ложно, элемент не существует в DOM вовсе — его там просто нет.

v-show

Директива v-show выглядит похоже, но работает иначе: элемент всегда присутствует в DOM, Vue лишь переключает CSS-свойство display:

<template>
  <div v-show="isOpen">Содержимое панели</div>
  <button @click="isOpen = !isOpen">Переключить</button>
</template>

<script setup>
import { ref } from 'vue'
const isOpen = ref(true)
</script>

Когда isOpen ложно, элемент получает display: none — он есть в разметке, но не виден.

v-if против v-show: что выбрать

Критерийv-ifv-show
Что делаетсоздаёт/удаляет элемент в DOMпереключает display
Цена переключениявыше (пересоздание)ниже (только CSS)
Цена при стартениже (не рендерит лишнее)выше (рендерит сразу)
v-else / v-else-ifподдерживаетнет

Практическое правило: если элемент часто переключается (например, вкладка, выпадашка) — берите v-show, чтобы не пересоздавать DOM. Если условие редко меняется или блок тяжёлый и в начале не нужен — берите v-if.

Аналогия в чистом JS

Чтобы прочувствовать разницу, представим выбор сообщения функцией. Так работает условный рендеринг по сути — возвращаем разный результат в зависимости от состояния:

function statusMessage(isOnline) {
  if (isOnline) return "В сети";
  return "Не в сети";
}

console.log(statusMessage(true));
console.log(statusMessage(false));

Вывод:

В сети
Не в сети

Итог

  • v-if / v-else-if / v-else добавляют и убирают элементы из DOM.
  • v-show всегда держит элемент в DOM и переключает CSS display.
  • Часто переключается — v-show; редко или тяжёлый блок — v-if.
  • v-show не поддерживает v-else.
Проверьте себя
1. Чем v-if отличается от v-show?
Av-if меняет цвет, v-show — размер
Bv-if добавляет/удаляет элемент из DOM, v-show оставляет его в DOM и переключает display
CЭто полные синонимы
Dv-show работает только с формами
2. Что выгоднее для элемента, который очень часто переключается (например, вкладка)?
Av-if — он легче
Bv-show — он не пересоздаёт DOM, а лишь меняет display
CБезразлично, разницы нет
DТолько v-else-if
3. Какая директива НЕ поддерживает v-else?
Av-if
Bv-else-if
Cv-show
DОбе v-if и v-else-if
Поддержать проект