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

Пользовательские директивы 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
Автор
Редакция

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

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро