> В чем разница v-if и v-show во Vue (Vue.js)

Уровень: senior · Роль: frontend · Категория: Технические вопросы

Компании: Библио-Глобус

Стек: Vue.js

> Пример ответа

Короткий ответ

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

Подробное объяснение

v-if - это условный рендеринг: при false элемент не создаётся в DOM, все его дочерние компоненты уничтожаются (вызываются lifecycle hooks beforeDestroy/destroyed). При true - создаётся заново (срабатывают created/mounted). Это дорого при частых переключениях, но экономит память, если условие редко меняется.

v-show всегда рендерит элемент в DOM, независимо от условия. Он просто применяет display: none через inline-стиль. Переключение происходит мгновенно, без lifecycle-затрат. Однако элемент остаётся в DOM, что может влиять на производительность при большом количестве скрытых узлов.

Ключевые различия:

  • Lifecycle: v-if триггерит хуки, v-show - нет.
  • Инициализация: v-if ленивый (не рендерит до первого true), v-show - нет.
  • CSS-свойства: v-show не работает с display: contents или visibility: hidden - он переопределяет display.
  • v-if с v-for: v-if имеет более высокий приоритет, чем v-for (до Vue 3), что может привести к ошибкам; v-show безопасен в паре с v-for.

На практике

Выбирайте v-if, когда:

  • Условие меняется редко (например, переключение вкладок).
  • Компонент дорогой (сложная логика, подписки, запросы).
  • Нужно избежать лишней загрузки данных (ленивая инициализация).

Выбирайте v-show, когда:

  • Условие переключается часто (например, hover-меню, анимации).
  • Элемент простой (див, иконка).
  • Важно сохранить состояние (например, позиция скролла или введённые данные).

Для SSR (Nuxt) v-if может быть предпочтительнее, так как v-show не скрывает элемент на сервере (нет display: none в серверном рендере).

Пример кода

<template>
  <div>
    <!-- v-if: элемент не в DOM при false -->
    <ExpensiveComponent v-if="isVisible" />
    
    <!-- v-show: элемент всегда в DOM, скрыт через display -->
    <div v-show="isToggled">Часто переключаемый блок</div>
    
    <!-- Плохая практика: v-if с частым переключением -->
    <button @click="toggle">Toggle</button>
  </div>
</template>

<script>
export default {
  data() {
    return {
      isVisible: false,
      isToggled: false
    }
  },
  methods: {
    toggle() {
      // Для частого переключения лучше v-show
      this.isToggled = !this.isToggled
    }
  }
}
</script>

Как отвечать на собеседовании

Начни с ключевого отличия: DOM vs CSS. Затем добавь про lifecycle и производительность. Приведи конкретный пример из опыта, где выбор между ними повлиял на производительность. Упомяни нюансы: v-if с v-for, SSR, v-show и display: contents. Покажи понимание trade-off: v-if экономит память, но дорог при переключении; v-show - наоборот.

Что проверяет интервьюер

  • Понимание работы Virtual DOM и lifecycle hooks.
  • Умение оценивать производительность рендеринга.
  • Знание практических кейсов и ограничений (SSR, приоритет директив).
  • Способность аргументировать выбор на основе контекста.

Типичные ошибки

  • Утверждение, что v-show использует visibility: hidden (на самом деле display: none).
  • Игнорирование lifecycle-затрат v-if при частых переключениях.
  • Использование v-show для дорогих компонентов с подписками (они остаются активными).
  • Применение v-if с v-for без понимания приоритета (в Vue 2 это может вызвать ошибку, в Vue 3 - работает корректно, но лучше избегать).

> ГОТОВЫ К СЛЕДУЮЩЕМУ СОБЕСЕДОВАНИЮ?

Запустите тренировочную сессию с ИИ и получите детальную обратную связь, чтобы увереннее проходить реальные интервью