Директивы: v-if и v-show, v-for и key, v-bind, v-on, v-model
↑ 4.1 Vue 3: основы, компоненты, Composition API · ← Предыдущая · → Следующая
Зачем это на собесе
v-ifпротивv-show, зачемkeyи почему нельзяv-ifвместе сv-for— вопросы каждого собеседования по Vue.
Объяснение
| Директива | Поведение |
|---|---|
v-if / v-else-if / v-else | условный рендеринг: элемент создаётся/уничтожается |
v-show | переключает display: none, элемент остаётся в DOM |
v-for | список: item in items, (item, i) in items, объекты, диапазоны |
v-bind (:) | привязка атрибутов/props; :class, :style, v-bind="obj" |
v-on (@) | события; модификаторы .prevent, .stop, .once, .self, .capture, .passive, .enter |
v-model | синхронизация value + input; модификаторы .trim, .number, .lazy |
v-once, v-memo, v-pre, v-cloak | оптимизации и служебные |
v-if vs v-show: v-if дороже при переключении (создание), но не тратит ресурсы, когда скрыт (ленивый); v-show дешёвый при частом переключении, но рендерится сразу.
<template>
<p v-if="loading">Загрузка...</p>
<ul v-else-if="orders.length">
<li v-for="order in orders" :key="order.id" @click.stop="open(order.id)">{{ order.number }}</li>
</ul>
<p v-else>Нет данных</p>
<input v-model.trim="query" @keyup.enter="search">
<li v-for="(value, key, index) in obj" :key="key" />
<span v-for="n in 5" :key="n">{{ n }}</span>
<button :disabled="!valid" :class="[base, { active }]">OK</button>
</template>key позволяет Vue сопоставлять элементы между рендерами и переиспользовать/перемещать их корректно. Ключ должен быть стабильным и уникальным (id), а не индексом, если список меняется (вставка, сортировка, удаление): иначе состояние (фокус, ввод, анимации) «прилипает» не к тем элементам.
v-if и v-for на одном элементе: во Vue 3 v-if имеет приоритет и не видит переменную цикла — используйте computed (фильтрация) или <template v-for> с v-if внутри.
Нюансы и подводные камни
v-forбезkeyили с индексом при динамическом списке — баги с состоянием.keyможно использовать и для принудительного пересоздания компонента.v-showне работает с<template>.v-modelнаnumberдаёт строку без.number.- Обработчики в шаблоне:
@click="fn"(ссылка) и@click="fn(arg)"(вызов при клике).
Практика
- Сделайте список с сортировкой и убедитесь, что
key = idсохраняет состояние инпутов. - Сравните
v-ifиv-showпо числу создаваемых узлов. - Отфильтруйте список через
computedвместоv-ifвнутриv-for.
Вопросы с ответами
Чем
v-ifотличается отv-show?
v-ifсоздаёт и уничтожает элемент,v-showтолько переключаетdisplay.
Зачем нужен
keyвv-for?Для корректного сопоставления и переиспользования элементов при изменении списка.
Можно ли
v-ifиv-forна одном элементе?Не рекомендуется:
v-ifвыполняется раньше и не видит переменную цикла; используйтеcomputedили вложенный<template>.