Vue.js директивы

Директивы во Vue.js представляют собой специальные атрибуты, расширяющие стандартный HTML и позволяющие привязывать поведение и данные к DOM-элементам. Каждая директива начинается с префикса v- и интерпретируется фреймворком на этапе компиляции шаблона.

Директивы обеспечивают декларативный подход к управлению интерфейсом, при котором логика описывается через связи между состоянием и представлением, а не через прямые манипуляции DOM.


Базовые директивы отображения данных

v-bind: динамическая привязка атрибутов

Директива v-bind используется для динамической привязки HTML-атрибутов к данным компонента.

Синтаксис:

<img v-bind:src="imageUrl" />

Сокращённая форма:

<img :src="imageUrl" />

Особенности:

  • поддерживает любые HTML-атрибуты
  • работает с объектами
  • может динамически менять классы и стили

Пример привязки объекта:

<div :class="{ active: isActive, disabled: isDisabled }"></div>

Привязка стилей:

<div :style="{ color: textColor, fontSize: fontSize + 'px' }"></div>

v-model: двусторонняя привязка данных

v-model создаёт синхронизацию между input-элементом и состоянием компонента.

<input v-model="username" />

Эквивалент ручной реализации:

<input
  :value="username"
  @input="username = $event.target.value"
/>

Используется с:

  • текстовыми полями
  • checkbox
  • radio
  • select
  • кастомными компонентами

Модификаторы:

.lazy — обновление по событию change

<input v-model.lazy="value" />

.number — преобразование в число

<input v-model.number="age" />

.trim — удаление пробелов

<input v-model.trim="text" />

Условный рендеринг

v-if, v-else-if, v-else

Директивы условного отображения управляют присутствием элементов в DOM.

<div v-if="isLoggedIn">Профиль</div>
<div v-else>Войти</div>

Цепочка условий:

<div v-if="status === 'loading'">Загрузка</div>
<div v-else-if="status === 'error'">Ошибка</div>
<div v-else>Готово</div>

Особенности:

  • элементы добавляются и удаляются из DOM
  • имеет высокую стоимость при частых переключениях
  • поддерживает <template> для группировки

v-show: управление видимостью

<div v-show="isVisible">Контент</div>

Отличия от v-if:

  • элемент всегда присутствует в DOM
  • управляет CSS-свойством display
  • быстрее при частом переключении

Работа со списками

v-for: рендеринг коллекций

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

Поддерживаемые формы:

Массив:

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

Индекс:

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

Объекты:

<div v-for="(value, key) in object" :key="key">
  {{ key }}: {{ value }}
</div>

Диапазоны:

<span v-for="n in 10" :key="n">{{ n }}</span>

Ключ key критически важен для корректного обновления виртуального DOM.


Обработка событий

v-on: привязка обработчиков

<button v-on:click="handleClick">Нажать</button>

Сокращение:

<button @click="handleClick">Нажать</button>

Передача аргументов:

<button @click="handleClick(id)">Удалить</button>

Доступ к событию:

<button @click="handleClick($event)">Клик</button>

Модификаторы событий

.stop — остановка всплытия

<button @click.stop="handleClick"></button>

.prevent — preventDefault

<form @submit.prevent="submitForm"></form>

.once — однократное выполнение

<button @click.once="init"></button>

.self — только на текущем элементе

<div @click.self="handle"></div>

Управление классами и стилями

Динамические классы

<div :class="{ active: isActive }"></div>

Массив классов:

<div :class="['base', condition ? 'active' : '']"></div>

Динамические стили

<div :style="{ backgroundColor: bgColor }"></div>

Директива v-html

Используется для вставки HTML-кода из строки.

<div v-html="rawHtml"></div>

Особенности:

  • полностью заменяет содержимое элемента
  • потенциальный источник XSS-уязвимостей
  • требует строгой санитаризации данных

Директива v-text

Альтернатива интерполяции {{ }}:

<div v-text="message"></div>

Полностью заменяет текстовое содержимое элемента.


Динамические аргументы директив

Vue позволяет использовать выражения в качестве аргументов:

<a v-bind:[attributeName]="url"></a>
<button v-on:[eventName]="handler"></button>

Особенности:

  • значение аргумента должно быть строкой
  • используется для универсальных компонентов
  • повышает гибкость шаблонов

Пользовательские директивы

Vue предоставляет возможность создавать собственные директивы для работы с DOM на низком уровне.

Регистрация локальной директивы:

directives: {
  focus: {
    mounted(el) {
      el.focus()
    }
  }
}

Использование:

<input v-focus />

Хуки жизненного цикла директив

Пользовательские директивы поддерживают набор хуков:

  • created
  • beforeMount
  • mounted
  • beforeUpdate
  • updated
  • beforeUnmount
  • unmounted

Пример:

app.directive('demo', {
  mounted(el, binding) {
    el.style.color = binding.value
  }
})

Аргументы и модификаторы в пользовательских директивах

Аргументы:

<div v-demo:foo="value"></div>

Модификаторы:

<div v-demo.uppercase="value"></div>

Доступ в директиве:

binding.arg
binding.modifiers
binding.value

Директива v-slot и связь с директивами

Хотя v-slot не является классической директивой DOM-уровня, она используется для управления распределением контента в компонентах.

<template v-slot:header>
  Заголовок
</template>

Сокращённая форма:

<template #header>
  Заголовок
</template>

Рендеринг без лишних узлов: v-once и v-memo

v-once

<div v-once>
  {{ staticContent }}
</div>

Элемент рендерится один раз и не обновляется.

v-memo (Vue 3)

<div v-memo="[value]">
  {{ value }}
</div>

Оптимизация повторного рендеринга при неизменных зависимостях.


Управление реактивностью через директивы

Директивы тесно связаны с реактивной системой Vue. Любое изменение состояния автоматически приводит к пересчёту шаблона и обновлению DOM, если директивы зависят от изменённых данных.

Механизм основан на:

  • отслеживании зависимостей
  • виртуальном DOM
  • дифференциальном обновлении

Приоритет выполнения и комбинации директив

На одном элементе может использоваться несколько директив:

<div v-if="show" v-for="item in list"></div>

Важно учитывать порядок обработки:

  • v-if имеет более высокий приоритет
  • v-for выполняется до условного рендеринга в некоторых сценариях компиляции

Расширенные паттерны использования

Комбинация v-model и кастомных компонентов:

<custom-input v-model="value" />

Эквивалент:

<custom-input
  :modelValue="value"
  @update:modelValue="value = $event"
/>

Работа директив формирует основу декларативного подхода Vue.js, обеспечивая управление DOM через связку реактивного состояния и шаблонов без необходимости прямых манипуляций элементами страницы.