Чем отличается v-if от v-show?
Во Vue.js v-if и v-show используются для условного отображения элементов, но работают они по-разному как логически, так и технически, и каждую директиву применяют в зависимости от контекста задачи.
Основное различие
Характеристика | v-if | v-show |
---|---|---|
Механизм | Удаляет/добавляет элемент в DOM | Просто прячет/показывает элемент через CSS (display: none) |
--- | --- | --- |
Начальная загрузка | Не рендерит, пока условие false | Рендерит всегда, но скрывает |
--- | --- | --- |
Производительность при переключениях | Медленно, т.к. каждый раз монтирует/размонтирует | Быстро, просто меняет стиль |
--- | --- | --- |
Затраты при первой отрисовке | Быстрее, если условие false, т.к. элемент не создаётся | Дольше, т.к. элемент рендерится всегда |
--- | --- | --- |
Использование | Когда нужно условно создавать/удалять элементы | Когда нужно часто показывать/скрывать без удаления |
--- | --- | --- |
Как работает v-if
v-if добавляет или удаляет элемент из DOM динамически. То есть при false элемент полностью исчезает из дерева DOM и Vue освобождает ресурсы (память, слушатели событий и т.д.).
<div v-if="isVisible">Контент</div>
Если isVisible = false, этого элемента вообще не будет в DOM. При true — он создаётся с нуля.
Это поведение особенно полезно, когда:
-
ты не хочешь, чтобы элемент загружался, пока не потребуется;
-
элемент тяжёлый и не нужен по умолчанию;
-
нужно инициировать заново каждый раз при отображении (например, загрузка данных, пересоздание компонента).
Также v-if поддерживает v-else и v-else-if:
<p v-if="type === 'A'">Тип A</p>
<p v-else-if="type === 'B'">Тип B</p>
<p v-else>Другой тип</p>
Как работает v-show
v-show всегда рендерит элемент в DOM, но управляет его видимостью через стиль display.
<div v-show="isVisible">Контент</div>
Если isVisible = false, элемент по-прежнему в DOM, но ему будет назначен стиль display: none, поэтому он не видим, но остаётся в памяти и может занимать ресурсы (например, прослушка событий).
Такой подход полезен, если:
-
тебе нужно часто показывать/прятать элемент без его пересоздания;
-
важна скорость переключения видимости;
-
элемент содержит внутреннее состояние, которое должно сохраняться между скрытием и показом.
Под капотом
Пример 1 — v-if
<template>
<button @click="toggle">Показать/Скрыть</button>
<div v-if="visible">Hello</div>
</template>
<script>
export default {
data() {
return {
visible: false
}
},
methods: {
toggle() {
this.visible = !this.visible
}
}
}
</script>
Когда visible = false, элемент <div> даже не существует в DOM. Vue отмонтирует его полностью, включая все дочерние компоненты, события, реактивные привязки.
Пример 2 — v-show
<template>
<button @click="toggle">Показать/Скрыть</button>
<div v-show="visible">Hello</div>
</template>
DOM всегда содержит этот <div>, но Vue просто переключает его стиль:
display: none;
Нет размонтирования, всё остаётся на месте, в том числе компоненты, слушатели, данные и т.д.
Когда использовать v-if
-
Элемент не должен загружаться, пока это не нужно.
-
Важно уменьшить нагрузку на DOM.
-
Нужно пересоздавать состояние при каждом отображении.
-
Тяжёлые компоненты, сетевые запросы, графики, табличные данные и пр.
Когда использовать v-show
-
Частое переключение отображения — кнопки, вкладки, модалки, тултипы.
-
Важна плавность отображения без потери состояния.
-
Компоненты лёгкие, нет смысла пересоздавать.
Примеры различий на практике
Диалоговое окно (часто показывается и скрывается):
<Modal v-show="isOpen" />
→ Используем v-show, чтобы сохранить состояние и моментально показывать/прятать.
Панель, которая показывается только после действия:
<Sidebar v-if="showSidebar" />
→ Используем v-if, потому что не хотим загружать компонент до клика.
Список, загружаемый с сервера:
<ul v-if="items.length > 0">
<li v-for="item in items" :key="item.id">{{ item.name }}</li>
</ul>
→ v-if помогает избежать показа пустых списков и не рендерит ничего, пока items не загружены.
Комбинированное использование
Иногда используют v-if и v-show совместно:
<template>
<Modal v-if="shouldMountModal" v-show="isModalVisible" />
</template>
-
v-if="shouldMountModal" решает, будет ли вообще компонент создан.
-
v-show="isModalVisible" решает, будет ли он видим.
Такой подход применяется, например, в сложных компонентах, где инициализация тяжёлая, но после этого нужна быстрая смена видимости.
Vue и ключи при v-if
Если в списке переключаются элементы с v-if, важно использовать :key, иначе Vue может не пересоздать компонент корректно:
<component :is="currentComponent" :key="currentComponent" />
Без key Vue может переиспользовать компонент, что приведёт к багам.
v-if и v-show — это инструменты с разными задачами: v-if управляет существованием элемента, а v-show — его видимостью. Выбор между ними влияет на производительность, реактивность и пользовательский опыт.