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

Vue.js — популярный JavaScript-фреймворк для создания динамичных веб-приложений. Он рендерит HTML на основе данных и событий, что упрощает создание интерактивных интерфейсов. Одним из ключевых механизмов управления отображением в шаблонах Vue являются директивы.
В этой статье мы рассмотрим, что такое директивы Vue, подробно разберём условный рендеринг с помощью v-if и v-show, покажем примеры, разберём типичные ошибки и предложим пошаговую методологию выбора между ними.
Что такое директивы Vue
Директивы Vue — это специальные атрибуты в шаблонах, которые расширяют поведение HTML-элементов. Они начинаются с префикса v- (например, v-if, v-show, v-for, v-bind, v-on). Директивы позволяют управлять DOM, связывать данные и реагировать на события.
Кратко:
- Директива — атрибут для управления DOM в шаблонах.
- Реактивность — механизм Vue, который отслеживает изменения данных и повторно рендерит части шаблона.
Что такое условный рендеринг
Условный рендеринг позволяет показывать или скрывать элементы в зависимости от условий. Это удобно, например, чтобы отображать сообщение об ошибке только при некорректном вводе или показывать список пользователей после загрузки данных.
Во Vue для этого чаще всего используют директивы v-if и v-show. Они похожи внешне, но работают по-разному и имеют разные сценарии применения.
v-if: как это работает
Директива v-if управляет наличием элемента в DOM. Если выражение ложно, Vue полностью не рендерит элемент — он не появляется в DOM вообще. При повторном возвращении истинного значения элемент создаётся заново.
Это похоже на условный оператор if в JavaScript: элемент либо есть в DOM, либо его нет.
Пример (оригинальный код сохранён):
Document
{{ message1 }}
{{ message2 }}
Пояснения:
- Элемент с v-if не присутствует в DOM, пока выражение ложно.
- При повторном монтировании компонент создаётся заново, поэтому состояние внутри элемента (например, значения в полях форм) будет сбрасываться при удалении и восстановлении.
Когда использовать v-if:
- Элемент рендерится редко (например, модальное окно, показываемое нечасто).
- Вы хотите экономить память и не держать в DOM тяжёлые элементы, пока они не нужны.
Ограничения и подводные камни v-if:
- Повторный монтинг может быть дорогим, если внутри компонента много логики и инициализаций.
- При использовании с v-for нужно быть аккуратным: сочетание может привести к сложным условиям рендеринга.
Пример с динамическим отображением списка (оригинал)
Vue app
- User1
- User2
{{ message }}
Этот пример демонстрирует простое условное отображение списка пользователей. Каждый раз при переключении showUsers контейнер с
v-show: как это работает
Директива v-show управляет видимостью элемента через CSS. При false элемент остаётся в DOM, но получает стиль display: none; при true — стиль удаляется и элемент снова виден.
Ключевое различие: v-show не монтирует и не размонтирует элемент, он всегда присутствует в DOM.
Оригинальный пример с v-show:
- User1
- User2
{{ message }}
Когда использовать v-show:
- Условие меняется часто (например, переключатели видимости в интерфейсе).
- Важно сохранить состояние элемента в DOM между показами (например, значения формы).
Ограничения v-show:
- Элемент всегда присутствует в DOM, поэтому он потребляет память и может влиять на производительность при большом количестве скрытых элементов.
- В сочетании с серверным рендерингом (SSR) поведение нужно учитывать отдельно: при SSR v-show управляет видимостью на клиенте, но элемент всё равно попадёт в изначальный HTML.
Сравнение v-if и v-show
| Критерий | v-if | v-show |
|---|---|---|
| Удаление из DOM | Да (монтируется/размонтируется) | Нет (только CSS: display) |
| Подходит для редких изменений | Да | Нет |
| Подходит для частых переключений | Нет | Да |
| Сохранение состояния внутри элемента | Нет (сброс при размонтировании) | Да |
| Влияние на начальную загрузку страницы | Может ускорять (меньше DOM) | Может замедлять при множестве скрытых элементов |
Важно: выбор зависит от сценария использования и объёма содержимого.
Частые ошибки и когда эти подходы не подходят
- Использовать v-show для очень тяжёлых компонентов, которые редко показываются — приведёт к лишнему потреблению памяти.
- Использовать v-if для элементов, которые переключаются десятки раз в секунду — приведёт к частым монтингам/размонтингам и потере состояния.
- Ожидать, что v-show управляет фокусом или жизненным циклом: скрытие через display не вызывает хуки жизненного цикла компонента.
- Использовать v-if внутри v-for без ключей (key) — может привести к неожиданному поведению при перестановке элементов.
Мини-методология: как выбрать (шаги)
- Оцените частоту переключений
- Редко: предпочитайте v-if.
- Часто: предпочитайте v-show.
- Нужна ли сохранность состояния компонента между показами?
- Да: v-show (или хранить состояние в родителе/хранилище).
- Нет: v-if.
- Насколько «тяжёлый» компонент с точки зрения рендеринга?
- Очень тяжёлый: v-if, чтобы не держать в DOM.
- Требуется ли, чтобы элемент присутствовал в начальном HTML (для SEO/SSR)?
- Если да: учтите, что v-show присутствует в HTML, v-if — может отсутствовать.
Чеклист приёмки (перед деплоем)
- Проверьте поведение при медленном устройстве: переключения не должны тормозить интерфейс.
- Убедитесь, что состояния форм сохраняются/сбрасываются в соответствии с ожиданиями.
- Добавьте ключи (key) при использовании v-for и условного рендеринга.
- Тестируйте SSR — проверьте, как выглядит начальная HTML-версия.
- Покройте автоматическими тестами сценарии показа/скрытия.
Дополнительные приёмы и альтернативы
- Динамическая отложенная загрузка: используйте динамический import() и defineAsyncComponent, чтобы загружать тяжёлые компоненты только когда они впервые отображаются.
- Комбинация с keep-alive: для сохранения состояния между переключениями можно обернуть динамические компоненты в
. - Использовать рендер-функции или Teleport для управления расположением в DOM.
Пример использования keep-alive (новый пример):
Этот шаблон сохраняет состояние HeavyComponent между показами при помощи keep-alive, но при этом сам компонент монтируется только когда showView истинно.
Совместимость и нюансы (SSR, transitions, accessibility)
- SSR: v-if влияет на то, что окажется в первоначальном HTML. Если контент важен для SEO или первичного рендера, учитывайте это.
- Transitions (переходы): v-show работает с CSS-переходами, но v-if запускает хуки монтирования/размонтирования — для анимаций можно комбинировать с
. - Доступность: при использовании v-show элемент остаётся в DOM и может быть доступен для скринридеров, даже если display: none; тестируйте доступность.
Краткая схема принятия решения (Mermaid)
flowchart TD
A[Начало] --> B{Часто ли будет меняться условие?}
B -- Да --> C[v-show]
B -- Нет --> D{Нужны ли ресурсы до показа?}
D -- Да --> C
D -- Нет --> E[v-if]
C --> F[Конец]
E --> FНебольшой глоссарий — 1 строка каждое
- Директива: атрибут v-*, управляющий поведением в шаблоне.
- DOM: Document Object Model — представление HTML в браузере.
- Реактивность: механизм Vue для отслеживания и реакции на изменения данных.
- v-if: директива, монтирует/размонтирует элемент в DOM в зависимости от условия.
- v-show: директива, переключает CSS display элемента, оставляя его в DOM.
Примеры тест-кейсов (приёмка)
- Переключение видимости 100 раз: UI не должен падать, состояние формы сохраняется (при v-show) или правильно сбрасывается (при v-if).
- Проверка с медленным подключением: отложенная загрузка компонентов не должна блокировать основной интерфейс.
- Тесты доступности: скрытый элемент не должен мешать навигации с клавиатуры.
Резюме
v-if и v-show решают одну задачу — условный рендеринг — но делают это по-разному. v-if удаляет элемент из DOM и подходит для редких изменений; v-show прячет элемент через display и лучше для частых переключений. Выбор зависит от частоты изменений, требований к сохранению состояния и производительности.
Важно: тестируйте конкретные сценарии вашего приложения (SSR, переходы, формы) и применяйте дополнительные приёмы — keep-alive, динамическую загрузку, ключи (key) — чтобы достичь ожидаемой UX и производительности.
Ключевые рекомендации:
- Если сомневаетесь, начните с v-if для простоты и минимального DOM; если понадобилось частое переключение — замените на v-show.
- Для тяжёлых компонентов используйте динамический импорт.
- Всегда тестируйте поведение на реальных устройствах.
Критерии приёмки
- UI соответствует ожиданиям в сценариях показ/скрытие.
- Производительность на целевых устройствах в пределах допустимого.
- Отсутствуют утечки памяти из-за большого количества скрытых элементов.
Похожие материалы
RDP: полный гид по настройке и безопасности
Android как клавиатура и трекпад для Windows
Советы и приёмы для работы с PDF
Calibration в Lightroom Classic: как и когда использовать
Отключить Siri Suggestions на iPhone