Директивы во Vue 3: условный рендеринг, циклы и создание своих директив

Vue 3 делает управление отображением элементов и поведением DOM невероятно гибким и простым.
Благодаря директивам — специальным атрибутам с префиксом v- — мы можем контролировать, когда и как элемент появляется, повторяется или реагирует на данные, не прибегая к ручным манипуляциям с DOM.

🧩 1. Что такое директивы во Vue

Директивы — это расширения стандартного HTML, которые позволяют Vue “понимать”, как нужно обновлять интерфейс при изменении данных.

Пример:

<template>
  <p v-if="isVisible">Привет, Vue!</p>
</template>

<script setup>
import { ref } from 'vue'

const isVisible = ref(true)
</script>

Здесь директива v-if управляет тем, будет ли элемент вообще существовать в DOM.
Когда isVisible становится false, Vue просто удаляет элемент со страницы.

⚙️ 2. Условный рендеринг: v-if и v-show

Иногда нужно показывать или скрывать элементы в зависимости от состояния.
Во Vue для этого есть две основные директивы — v-if и v-show.

🟢 v-if — элемент создаётся или удаляется из DOM

<template>
  <button @click="toggle">Показать / скрыть</button>
  <p v-if="isVisible">Я появляюсь и исчезаю!</p>
</template>

<script setup>
import { ref } from 'vue'
const isVisible = ref(true)
const toggle = () => isVisible.value = !isVisible.value
</script>

Когда isVisible = false, элемента просто нет в DOM.

🔵 v-show — элемент всегда в DOM, но скрыт через CSS

<template>
  <button @click="toggle">Показать / скрыть</button>
  <p v-show="isVisible">Я только скрываюсь</p>
</template>

<script setup>
import { ref } from 'vue'
const isVisible = ref(true)
const toggle = () => isVisible.value = !isVisible.value
</script>

Vue не удаляет элемент, а просто меняет стиль display: none.

💡 Совет:
Используй v-show, если элемент часто меняет видимость (например, модальное окно).
Если элемент нужен только изредка — v-if.

🔁 3. Рендеринг списков с помощью v-for

Vue позволяет легко отображать списки данных с помощью директивы v-for.

<template>
  <ul>
    <li v-for="user in users" :key="user.id">
      {{ user.name }}
    </li>
  </ul>
</template>

<script setup>
const users = [
  { id: 1, name: 'Анна' },
  { id: 2, name: 'Борис' },
  { id: 3, name: 'Света' }
]
</script>

🧠 Зачем нужен key

Атрибут :key помогает Vue отслеживать, какой элемент списка изменился.
Без него фреймворк может “перепутать” элементы при обновлении.

Плохо:

<li v-for="(user, i) in users" :key="i">{{ user.name }}</li>

Хорошо:

<li v-for="user in users" :key="user.id">{{ user.name }}</li>

💡 Лучше всегда использовать уникальные ключи (ID), особенно при добавлении или удалении элементов из списка.

🛠️ 4. Создание кастомных директив

Иногда встроенных директив недостаточно — например, нужно автоматически сфокусировать поле при загрузке страницы или добавить визуальный эффект при наведении.

🔹 Пример 1. Автофокус (v-focus)

<template>
  <input v-focus placeholder="Поле с автофокусом" />
</template>

<script setup>
const vFocus = {
  mounted(el) {
    el.focus()
  }
}
</script>

Теперь при монтировании элемента Vue вызовет el.focus(), и курсор окажется в этом поле.

Если директива нужна везде — можно зарегистрировать её глобально в main.js:

app.directive('focus', {
  mounted(el) {
    el.focus()
  }
})

🔹 Пример 2. Изменение цвета текста (v-color)

<template>
  <p v-color="'tomato'">Красный текст</p>
</template>

<script setup>
const vColor = {
  mounted(el, binding) {
    el.style.color = binding.value
  }
}
</script>

binding.value — это значение, переданное в директиву (в нашем случае 'tomato').

🚀 Заключение

Теперь вы знаете:

  • Как управлять условным отображением элементов через v-if и v-show;

  • Как работать со списками с помощью v-for и зачем нужен key;

  • Как создавать собственные директивы для расширения поведения элементов.