логотип PurpleSchool
логотип PurpleSchool

Основы и применение директив в Vue

Автор

Олег Марков

Введение

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

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

В Vue директива — это специальный атрибут (обычно с префиксом v-), который вы добавляете к HTML-элементу для связывания с определённым поведением данного элемента. Когда Vue компилирует шаблон, он обрабатывает эти директивы, чтобы добавить логику работы с DOM.

Например, директива v-if решает, показывать или скрывать элемент, а v-model обеспечивает двустороннюю связь данных с полями формы.

Почему это важно

Директивы позволяют отделить логику представления от бизнес-логики, делая ваш шаблон мощнее и выразительнее. Это снижает объем кода и повышает его читаемость.

Встроенные директивы Vue

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

v-bind

Директива v-bind привязывает атрибут HTML к выражению на вашем экземпляре Vue.

<!-- Пример: делаем динамический src у картинки -->
<img v-bind:src="imageSrc" alt="Картинка">
// В data у компонента
data() {
  return {
    imageSrc: 'https://picsum.photos/200'
  }
}

v-bind:src можно коротко записать как :src. Также такое связывание работает с любым атрибутом, не только с src.

v-model

Директива v-model используется для двусторонней привязки между данными и элементом формы.

<input v-model="email" placeholder="Введите почту">
// Теперь email в data будет обновляться вместе с вводом пользователя
data() {
  return {
    email: ''
  }
}

Это невероятно удобно для создания форм, где изменения от пользователя должны мгновенно отображаться в состоянии компонента.

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

С помощью этих директив вы управляете видимостью элементов на основе условий.

<p v-if="user">Добро пожаловать, {{ user.name }}!</p>
<p v-else>Пожалуйста, авторизуйтесь</p>

Когда user определён, показывается приветствие. Если user равен null, показывается другой текст.

v-show

Если вам нужно часто скрывать и показывать элементы, вместо v-if используйте v-show. Отличие: v-if добавляет или убирает элемент из DOM, а v-show просто переключает свойство display через CSS.

<div v-show="isVisible">Этот блок спрятан, но всё равно остаётся в DOM</div>

v-for

Для вывода списков часто применяется v-for.

<ul>
  <li v-for="item in items" :key="item.id">
    {{ item.text }}
  </li>
</ul>
data() {
  return {
    items: [
      { id: 1, text: 'Пункт 1' },
      { id: 2, text: 'Пункт 2' },
    ]
  }
}

v-for требует обязательное указание ключа через :key — это важно для оптимизации внутренней работы Vue.

v-on

Директива v-on привязывает обработчики событий к элементам.

<button v-on:click="doSomething">Кликните меня</button>
methods: {
  doSomething() {
    // Ваш код обработки события
  }
}

Аналогичная короткая форма — @click.

Модификаторы и аргументы директив

У многих директив есть модификаторы и аргументы, которые позволяют ещё больше контролировать их поведение.

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

Модификаторы — это специальные суффиксы, указываемые после точки.

<input v-model.lazy="message">
// Обновит message только при событии "change", а не "input"
<form v-on:submit.prevent="handleSubmit">
// Не отправит форму по умолчанию, только вызовет handleSubmit

Аргументы

Аргументы позволяют передавать дополнительные параметры, например, имя атрибута или название события.

<!-- v-bind с аргументом href -->
<a v-bind:href="url">Ссылка</a>
<!-- или коротко -->
<a :href="url">Ссылка</a>

<!-- v-on с аргументом click -->
<button v-on:click="clickHandler">Нажми меня</button>
<!-- или коротко -->
<button @click="clickHandler">Нажми меня</button>

Жизненный цикл директив

Внутри Vue каждой директиве выделяется определённый жизненный цикл. Если вы создаёте свою директиву, вы сможете использовать специальные хуки жизненного цикла:

  • created — вызывается один раз при инициализации
  • beforeMount — до вставки элемента в DOM
  • mounted — когда элемент добавлен в DOM
  • beforeUpdate — перед обновлением компонента
  • updated — после обновления компонента
  • beforeUnmount — перед удалением
  • unmounted — после удаления из DOM

Обычно используются хуки mounted и updated, чтобы подписаться на события или взаимодействовать с DOM.

Создание пользовательских директив

Иногда стандартных директив недостаточно — тогда пригодятся пользовательские директивы. Вы можете зарегистрировать директиву глобально или локально.

Глобальная регистрация

// Регистрируем глобально
app.directive('focus', {
  mounted(el) {
    el.focus();
  }
});

В шаблоне используете так:

<input v-focus>

Когда этот инпут появится, он сразу получит фокус. Попробуйте в своём проекте — вы заметите, как просто это работает.

Локальная регистрация

Если не надо использовать директиву по всему приложению, удобно регистрировать её только в конкретном компоненте.

export default {
  directives: {
    focus: {
      mounted(el) {
        el.focus();
      }
    }
  }
}

Теперь внутри этого компонента директива доступна так же, как глобальная.

Подробный пример директивы

Реализуем директиву, которая меняет цвет текста элемента на указанный.

// Регистрируем директиву v-color глобально
app.directive('color', {
  mounted(el, binding) {
    // binding.value содержит значение, переданное в директиву
    el.style.color = binding.value;
  },
  updated(el, binding) {
    // При обновлении значения мы также меняем цвет
    el.style.color = binding.value;
  }
});

В шаблоне используйте вот так:

<p v-color="'red'">Этот текст станет красным</p>
<p v-color="textColor">А этот — цветом из data</p>

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

Можно добавить поддержку аргументов и модификаторов, чтобы ваша директива стала гибче.

// Директива для задания цвета и фона
app.directive('colorful', {
  mounted(el, binding) {
    // binding.arg — аргумент директивы (например, "background")
    // binding.modifiers — наличие модификаторов, например .bold
    if (binding.arg === 'background') {
      el.style.backgroundColor = binding.value;
    } else {
      el.style.color = binding.value;
    }

    if (binding.modifiers.bold) {
      el.style.fontWeight = 'bold';
    }
  }
});
<span v-colorful.bold="'green'">Зеленый и жирный</span>
<span v-colorful:background="'yellow'">Желтый фон</span>

Практические примеры использования директив

Для чего реально нужны пользовательские директивы? Вот несколько классических сценариев:

  • Автоматическая фокусировка в поля ввода при открытии формы (v-focus)
  • Слежение за кликом вне определенного блока для закрытия выпадающего меню (v-click-outside)
  • Эффекты или анимации при наведении мыши (v-hover)
  • Маски для полей ввода
  • Drag & Drop функциональность

Пример: v-click-outside

Давайте реализуем простую директиву, которая подслушивает клики вне элемента.

app.directive('click-outside', {
  mounted(el, binding) {
    // Создаем обработчик
    el.__vueClickOutside__ = event => {
      // Если клик был вне элемента — вызываем функцию
      if (!(el === event.target || el.contains(event.target))) {
        binding.value(event);
      }
    }
    document.body.addEventListener('click', el.__vueClickOutside__);
  },
  unmounted(el) {
    document.body.removeEventListener('click', el.__vueClickOutside__);
    el.__vueClickOutside__ = null;
  }
});

В шаблоне:

<div v-click-outside="closeMenu">Меню...</div>
methods: {
  closeMenu() {
    // Здесь код для скрытия меню
  }
}

Как видите, теперь обработчик сработает, если клик был за пределами блока — это очень удобно для закрытия модальных окон, тултипов, dropdown-меню.

Ограничения и рекомендации при работе с директивами

  • Не используйте директивы там, где проще обойтись computed-свойствами или методами.
  • Внутри пользовательских директив избегайте сложной бизнес-логики — они должны решать только задачи, связанные с работой DOM.
  • Следите за утечкой обработчиков событий — всегда корректно очищайте их в хуке unmounted.
  • Старайтесь делать свои директивы универсальными — принимайте аргументы и модификаторы для максимальной гибкости.

Тонкости работы директив в Vue 3

В Vue 3 структура директив почти не изменилась по сравнению с Vue 2, но секция хуков теперь используется под новыми названиями и рекомендуется использовать функцию вместо объекта, если нужен только один хук (обычно mounted). Также теперь регистрация директив идет через экземпляр приложения (app.directive вместо глобального Vue в Vue 2).

Вот пример краткой директивы только с функцией:

app.directive('autofocus', el => el.focus());

Если нужны жизненные циклы, используйте объект с нужными хуками:

app.directive('custom', {
  mounted(el, binding, vnode, prevVnode) {
    // Ваша логика
  },
  updated(el, binding, vnode, prevVnode) {
    // Ваша логика
  }
});

Заключение

Директивы делают шаблоны Vue лаконичнее, а управление DOM — более мощным и декларативным. Разобравшись с их синтаксисом, аргументами, модификаторами и жизненным циклом, вы получите простой и расширяемый способ добавлять интерактивность и реактивность в свои компоненты. Создание собственных директив позволит покрыть особые сценарии, с которыми стандартные средства не справляются так элегантно. Используйте директивы осознанно, не забывая об их ограничениях и лучшем применении.

Частозадаваемые технические вопросы по теме статьи и ответы на них

Как получить доступ к аргументам и модификаторам внутри своей директивы?

Внутри пользовательской директивы в параметре binding доступны:

  • binding.value — основное значение;
  • binding.arg — аргумент директивы (например, цвет или имя атрибута);
  • binding.modifiers — объект с булевыми значениями для каждого модификатора. Например: js mounted(el, binding) { console.log(binding.value); // ваше значение console.log(binding.arg); // аргумент console.log(binding.modifiers); // { bold: true, italic: false } }

Как корректно снять обработчики событий внутри директивы?

Сохраняйте свой обработчик на элементе (например, el.__myHandler__ = fn) и в хуке unmounted удаляйте его: js mounted(el) { el.__myHandler__ = event => { /* ... */ }; document.addEventListener('click', el.__myHandler__); }, unmounted(el) { document.removeEventListener('click', el.__myHandler__); }

Как передать несколько параметров в пользовательскую директиву?

Передавайте объект как значение: html <div v-my-directive="{ color: 'red', size: 12 }"></div> В директиве: js mounted(el, binding) { const { color, size } = binding.value; // дальше используете color и size }

Как использовать директиву только в одном компоненте (локально)?

Добавьте директиву в объект directives компонента: js export default { directives: { myDirective: { mounted(el) { /* ... */ } } } } Теперь директива доступна только в этом компоненте.

Можно ли в директивах корректировать содержимое слота?

Директивы применяются к рендеренному элементу и не могут вмешиваться в логику или содержимое слотов на этапе компиляции. Для управления содержимым слотов используйте computed-свойства или шаблонную логику родительского компонента.

Стрелочка влевоИспользование директив в Vue и их расширенные возможностиИспользование директив и их особенности на Vue с помощью defineСтрелочка вправо

Все гайды по Vue

Руководство по валидации форм во Vue.jsИнтеграция Tiptap для создания редакторов на VueРабота с таблицами во Vue через TanStackИнструкция по установке и компонентам Vue sliderУправление пакетами Vue js с помощью npmУправление пакетами и node modules в Vue проектахКак использовать meta для улучшения SEO на VueПолный гайд по компоненту messages во Vuejs5 правил использования Inertia с Vue и LaravelРабота с модулями и пакетами в VueИнструкция по работе с grid на VueGithub для Vue проектов - подробная инструкция по хранению и совместной работеНастройка ESLint для Vue проектов и поддержка качества кодаОбработка ошибок и отладка в Vue.jsИспользование Vue Devtools для отладки и мониторинга приложенийРабота с конфигурационными файлами и скриптами VueСоздание и настройка проектов Vue с помощью Vue CLI3 способа интеграции Chart.js с Vue для создания графиковРабота с Canvas во VueИнструкция по реализации календаря во VueРабота с Ant Design Vue для создания UI на Vue
Обзор и использование утилит Vue для удобной разработкиРабота с обновлениями компонента и жизненным циклом updateРазрешение конфликтов и ошибок с помощью Vue resolveИспользование query-параметров и их обработка в маршрутах VueЗагрузка и управление состоянием загрузки в VueИспользование библиотек Vue для расширения функционалаРабота с JSON данными в приложениях VueКак работать с экземплярами компонента Instance во VueПолучение данных и API-запросы во Vue.jsЭкспорт и импорт данных и компонентов в VueОбработка событий и их передача между компонентами VuejsГайд по defineEmits на Vue 3Понимание core функционала Vue и его применениеПонимание и применение Composition API в Vue 3Понимание и работа с компилятором VueКогда и как использовать $emit и call во VueВзаимодействие с внешними API через Axios в Vue
Веб приложения на Vue архитектура и лучшие практикиИспользование Vite для быстрого старта и сборки проектов на Vue 3Работа с URL и ссылками в приложениях на VueРабота с пользовательскими интерфейсами и UI библиотеками во VueОрганизация и структура исходных файлов в проектах VueИспользование Quasar Framework для разработки на Vue с готовыми UI-компонентамиОбзор популярных шаблонов и стартовых проектов на VueИнтеграция Vue с PHP для создания динамичных веб-приложенийКак организовать страницы и маршруты в проекте на VueNuxt JS и Vue 3 для SSR приложенийСоздание серверных приложений на Vue с помощью Nuxt jsИспользование Vue Native для разработки мобильных приложенийОрганизация и управление индексной страницей в проектах VueИспользование Docker для контейнеризации приложений на VueИнтеграция Vue.js с Django для создания полноценных веб-приложенийСоздание и работа с дистрибутивом build dist Vue приложенийРабота со стилями и CSS в Vue js для красивых интерфейсовСоздание и структурирование Vue.js приложенияКак исправить ошибку cannot find module vueНастройка и сборка проектов Vue с использованием современных инструментовИнтеграция Vue с Bitrix для корпоративных решенийРазработка административных панелей на Vue js
5 библиотек для создания tree view во VueИнтеграция Tailwind CSS с Vue для современных интерфейсовИнтеграция Vue с серверной частью и HTTPS настройкамиКак обрабатывать async операции с Promise во VueИнтеграция Node.js и Vue.js для разработки приложенийРуководство по интеграции Vue js в NET проектыПримеры использования JSX во VueГайд по импорту и регистрации компонентов на VueМногоязычные приложения на Vue с i18nИнтеграция FLIR данных с Vue5 примеров использования filter во Vue для упрощения разработки3 примера реализации drag-and-drop во Vue
Управление переменными и реактивными свойствами во VueИспользование v for и slot в VueПрименение v-bind для динамической привязки атрибутов в VueУправление пользователями и их данными в Vue приложенияхСоздание и использование UI Kit для Vue приложенийТипизация и использование TypeScript в VuejsИспользование шаблонов в Vue js для построения интерфейсовИспользование Swiper для создания слайдеров в VueРабота со стилями и стилизацией в VueСтруктура и особенности Single File Components SFC в VueРабота со SCSS в проектах на Vue для стилизацииРабота со скроллингом и прокруткой в Vue приложенияхПрименение script setup синтаксиса в Vue 3 для упрощения компонентовИспользование scoped стилей для изоляции CSS в компонентах Vue3 способа улучшить навигацию Vue с push()Обработка запросов и асинхронных операций в VueПонимание и использование provide inject для передачи данных между компонентамиПередача и использование props в Vue 3 для взаимодействия компонентовПередача данных между компонентами с помощью props в Vue jsУправление property и функциями во Vue.jsРабота со свойствами компонентов VueУправление параметрами и динамическими данными во VueРабота с lifecycle-хуком onMounted во VueОсновы работы с объектами в VueПонимание жизненного цикла компонента Vue js на примере mountedИспользование модальных окон modal в Vue приложенияхИспользование методов в компонентах Vue для обработки логикиИспользование метода map в Vue для обработки массивовИспользование хуков жизненного цикла Vue для управления состоянием компонентаРабота с ключами key в списках и компонентах VueОбработка пользовательского ввода в Vue.jsРабота с изображениями и их оптимизация в VueИспользование хуков жизненного цикла в VueОрганизация сеток и гридов для верстки интерфейсов на VueСоздание и управление формами в VueОрганизация файлов и структура проекта Vue.jsКомпоненты Vue создание передача данных события и emitРабота с динамическими компонентами и данными в Vue3 способа манипулирования DOM на VueРуководство по div во VueИспользование директив в Vue и их расширенные возможностиОсновы и применение директив в VueИспользование директив и их особенности на Vue с помощью defineИспользование компонентов datepicker в Vue для выбора датОрганизация циклов и итераций во VueКак работает компиляция Vue CoreСоздание и использование компонентов в Vue JSОбработка кликов и пользовательских событий в VueИспользование классов в Vue для организации кода и компонентовИспользование директивы checked для управления состоянием чекбоксов в VueГайд на checkbox компонент во VueОтображение данных в виде графиков с помощью Vue ChartСоздание и настройка кнопок в VueСоздание и настройка кнопок в Vue приложенияхРабота с lifecycle-хуками beforeCreate и beforeMount во VueИспользование массивов и методов их обработки в VueИспользование массивов и их обработка в Vue
Использование Vuetify для создания современных интерфейсов на VueИспользование transition во VueТестирование компонентов и приложений на VueРабота с teleport для управления DOM во VueПять шагов по настройке SSR в VuejsИспользование Shadcn UI компонентов с Vue для продвинутых интерфейсовИспользование router-link для навигации в Vue RouterКак использовать require в Vue для динамического импорта модулейРабота с динамическим рендерингом и виртуальным DOM на Vue.jsИспользование ref для управления ссылками и реактивностью в Vue 3Использование Vue Pro и его преимущества для профессиональной разработкиРуководство по nextTick для работы с DOMСоздание и использование компонентов с помощью Vue js и CУправление состоянием и реактивностью через inject и provideДинамическое обновление компонентов и данных на VueГлубокое изучение документации Vue и как эффективно её использоватьИспользование Crystal с Vue для разработкиИспользование вычисляемых свойств для динамического отображения данных на Vue jsОптимизация производительности и предупреждения в Vue
Открыть базу знаний