Гид по технологиям

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

6 min read Frontend Обновлено 05 Jan 2026
Пользовательские директивы Vue: создать и применить
Пользовательские директивы Vue: создать и применить

TL;DR

Пользовательские директивы Vue дают низкоуровневый доступ к DOM и позволяют переиспользовать поведение между компонентами. В этой статье объясняю структуру директив, показываю локальную и глобальную регистрацию, примеры реализации (включая короткую форму) и даю практические чеклисты, критерии приёмки и рекомендации по отладке.

Что такое директива Vue и зачем она нужна

Директивы — это конструкции, которые подсказывают компилятору и рантайму, как обрабатывать атрибуты в шаблоне. В Vue директивы расширяют поведение HTML-элементов в шаблонах и позволяют напрямую взаимодействовать с DOM.

Короткое определение: директива — это привязка к элементу, управляющая его поведением на уровне DOM.

Примеры задач, которые решают директивы:

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

Важно: директивы не заменяют компоненты и не должны содержать бизнес-логику приложения. Пользуйтесь ими, когда нужен прямой доступ к DOM или повторяемое низкоуровневое поведение.

Структура директив Vue

Директивы Vue помечаются префиксом v- чтобы отличать их от обычных HTML-атрибутов. Префикс говорит компилятору Vue, что атрибут — директива и её поведение нужно применить к элементу.

Пример использования встроенной директивы v-show:

Hello Vue

Кроме v-show, Vue предоставляет v-bind, v-if, v-on и другие готовые директивы для привязки данных, условного рендеринга и обработки событий.

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

Вы можете создать собственные директивы, если нужно переиспользуемое поведение для элементов. Процесс состоит из двух шагов: регистрация (локальная или глобальная) и определение поведения через хуки жизненного цикла директивы.

Регистрация директив

Директиву можно регистрировать локально внутри компонента или глобально для всего приложения. Чаще регистрируют глобально, когда поведение нужно в разных местах приложения. Локальную регистрацию выбирают для простых или одноразовых сценариев.

Пример локальной регистрации (внутри компонента):



В этом примере директива определена как объект в camelCase (changeColor), но в шаблоне её пишут через дефис v-changecolor.

Пример глобальной регистрации (main.js):

// main.js
import { createApp } from 'vue'
import App from './App.vue'

const app = createApp(App)

app.directive('changecolor', {
    mounted(el, binding, vnode) {
    }
})

app.mount('#app')

app.directive регистрирует директиву в глобальной области видимости приложения.

Поведение директивы через хуки

Директивы определяют поведение через хуки жизненного цикла: created, mounted, updated и другие. Хуки получают ссылку на элемент (el), объект binding и виртуальный узел vnode.

Пример объекта с хуками:

const directiveObject = {
    mounted(el, binding, vnode) {
    },

    updated(el, binding, vnode) {
    }
}

app.directive('changecolor', directiveObject)

Если поведение одинаково для mounted и updated, часто удобнее определить директиву как функцию (shorthand). В этом случае функция будет вызываться при монтировании и обновлении:

app.directive('changecolor', (el, binding, vnode) => {
    const message = 'Are you sure you want to change the color?'

    el.addEventListener('click', () => {
        if (confirm(message)) {
            el.style.color = binding.value
             || "#" + Math.random().toString().slice(2, 8);
        }
    })
})

В этом примере директива изменяет цвет элемента по клику. Параметры функции:

  • el — реальный DOM-элемент, к которому привязана директива;
  • binding — объект с информацией о привязке (включая binding.value);
  • vnode — виртуальный узел Vue.

Пример тестового компонента





Результат: элемент h2 получает цвет red из binding.value, h3 — случайный цвет при клике. Скриншоты ниже показывают состояние до и после подтверждения.

Ноутбук на столе с редактором кода на тёмном фоне.

Предпросмотр простого Vue-приложения до подтверждения.

Предпросмотр простого Vue-приложения после подтверждения.

Когда не стоит использовать директивы

  • Когда задачу можно решить декларативно через компонент.
  • Когда логика сложная и зависит от состояния приложения — лучше использовать композицию и слоты.
  • Для отображения UI, завязанного на reactive-потоках, компонент читабельнее и тестируемее.

Пример плохого применения: реализация сложного виджета с внутренним состоянием через директиву. В этом случае компоненты читаются и поддерживаются легче.

Альтернативные подходы

  • Компоненты — для визуальных/функциональных блоков с собственным состоянием.
  • Composition API — для повторно используемой логики без доступа к DOM.
  • Плагины — для глобальной функциональности без привязки к конкретным элементам.

Выбор: если нужен доступ к DOM — директива; если нужна UI-логика и рендер — компонент.

Практические шаблоны и хорошая практика

  • Всегда удаляйте слушатели событий в хуке перед размонтированием (unmounted), чтобы избежать утечек памяти.
  • Не храните сложное состояние внутри директивы. Пусть директива выполняет одну очевидную задачу.
  • Документируйте API директивы: какие аргументы и значения binding.value ожидаются.
  • Используйте имена в стиле kebab-case в шаблоне и camelCase в коде, если регистрируете локально.

Пример с отпиской слушателя:

app.directive('safe-click', {
  mounted(el, binding) {
    const handler = () => binding.value && binding.value()
    el.__safeClickHandler__ = handler
    el.addEventListener('click', handler)
  },
  unmounted(el) {
    el.removeEventListener('click', el.__safeClickHandler__)
    delete el.__safeClickHandler__
  }
})

В этом шаблоне мы сохраняем ссылку на обработчик в свойстве DOM-элемента, чтобы корректно отписаться при unmounted.

Чеклист перед релизом (для разработчика и ревьюера)

  • Директива покрыта краткой документацией.
  • Есть тесты, симулирующие жизненный цикл (mount/update/unmount).
  • Отписка от событий реализована.
  • Нет побочного состояния внутри директивы.
  • Публичный API (binding.value, аргументы) понятен и стабилен.
  • Производительность — нет частых пересозданий слушателей.

Критерии приёмки

  • Директива выполняет заявленную задачу на всех целевых браузерах.
  • Нет утечек памяти при множественном создании/удалении элементов.
  • Поведение согласовано с документацией (пример использования и edge-case описаны).
  • Наличие unit/e2e теста, проверяющего мажорные сценарии.

Runbook: отладка и откат

  • Симптом: элемент перестал реагировать на директиву. Шаги:
    1. Проверьте регистрацию директивы (глобальная vs локальная).
    2. Убедитесь, что в mounted происходит добавление слушателей.
    3. Проверьте, не перезаписано ли свойство el.handler где-то ещё.
    4. Воспроизведите проблему в минимальном компоненте.
  • Откат: замените использование директивы на временный компонент-обёртку для изоляции проблемы.

Тестовые случаи/Acceptance

  • Простой сценарий: элемент с binding.value = ‘red’ меняет цвет на red после подтверждения.
  • Сценарий без value: элемент получает случайный цвет и его цвет меняется.
  • Повторное монтирование: несколько элементов используют директиву — отсутствие пересечений между элементами.
  • Удаление элемента: отсутствуют ошибки в консоли, слушатели удалены.

Decision flowchart

flowchart TD
  A[Нужен доступ к DOM?] -->|Да| B[Должно ли поведение быть переиспользуемым?]
  A -->|Нет| C[Используйте компонент или Composition API]
  B -->|Да| D[Создайте директиву]
  B -->|Нет| C
  D --> E[Регистрация: глобально или локально?]
  E -->|Глобально| F[app.directive'...']
  E -->|Локально| G[Определить в компоненте]

Ментальные модели и эмпирические правила

  • «Директива = локальная трансформация элемента». Если задача касается структуры UI или состояний — выберите компонент.
  • Минимализм: одна директива — одна ответственность.
  • Безопасность: предполагаем, что любая директива может работать с внешними библиотеками, поэтому проверяйте входные данные и используйте защитные проверки.

Совместимость и миграция

  • Vue 3 и Composition API — текущая рекомендация для новых приложений. Директивы совместимы с Vue 3, но API регистрации отличается от Vue 2.
  • При миграции с Vue 2 на Vue 3: проверьте хуки (могут отличаться имена и порядок вызовов) и способ регистрации глобальных директив.

Безопасность и конфиденциальность

  • Директивы, которые вставляют HTML или работают с внешними данными, должны очищать вход (sanitize) и избегать вставки неподготовленного HTML.
  • Не храните чувствительные данные в свойствах DOM-элемента.

Краткий план внедрения (Playbook)

  1. Описать цель директивы и API (binding.value, аргументы).
  2. Сделать минимальную реализацию (mounted).
  3. Добавить обработку обновлений (updated) при необходимости.
  4. Реализовать очистку ресурсов (unmounted).
  5. Написать unit-тесты и интеграционные тесты.
  6. Добавить документацию и примеры использования.
  7. Развернуть и мониторить метрики ошибок.

Глоссарий (1 строка)

  • binding — объект, содержащий value, arg, modifiers для текущей привязки;
  • vnode — виртуальный узел Vue, содержащий метаданные компонента;
  • mounted/updated/unmounted — хуки жизненного цикла директивы.

Итог

Пользовательские директивы Vue — мощный инструмент для управления поведением отдельных элементов и интеграции с низкоуровневыми API браузера. Используйте их, когда нужен прямой доступ к DOM и при этом сохраняйте простоту и читабельность. Всегда документируйте API директивы, очищайте ресурсы и добавляйте тесты.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как обновить прошивку Microsoft Surface
Обновления

Как обновить прошивку Microsoft Surface

Как собрать портативный MP3‑плеер на DFPlayer
Электроника

Как собрать портативный MP3‑плеер на DFPlayer

Как извлечь максимум из поездки на работу
Лайфстайл

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

Как изучать новый subreddit: подробное руководство
Социальные сети

Как изучать новый subreddit: подробное руководство

Почему iPhone разряжается ночью и как исправить
Советы iPhone

Почему iPhone разряжается ночью и как исправить

Автообновления сторонних приложений на Mac с AppFresh
macOS

Автообновления сторонних приложений на Mac с AppFresh