Пользовательские директивы
Регистрируйте глобальные и локальные директивы с хуками жизненного цикла, такими как mounted и updated, чтобы вынести логику работы с DOM за пределы компонентов
«Пользовательские директивы» — бесплатный урок Frontend Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Frontend Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Frontend Academy содержит 4 уроков всего.
Что такое директивы
Директивы — это повторно используемая логика манипуляции DOM, прикрепляемая к элементам с помощью префикса v-. Встроенные примеры: v-if, v-for, v-model и v-show. Пользовательские директивы позволяют создавать собственные директивы.
Пример: автофокусировка
Директива может инкапсулировать небольшие фрагменты логики манипуляции DOM, для которых не стоит создавать компонент-обёртку.
<template>
<input v-focus>
</template>
<script setup>
const vFocus = {
mounted: (el) => el.focus()
};
</script>Локальная регистрация директивы
В <script setup> объявляйте директивы с префиксом v — Vue автоматически зарегистрирует их локально.
<script setup>
const vColor = {
mounted: (el, binding) => {
el.style.color = binding.value;
}
};
</script>
<template>
<p v-color="'red'">Hello</p>
</template>Глобальная регистрация директивы
Используйте app.directive(name, definition), чтобы сделать директиву доступной повсюду.
// main.ts
const app = createApp(App);
app.directive('focus', {
mounted: (el) => el.focus()
});
app.mount('#app');Хуки жизненного цикла директивы
У директив есть хуки, соответствующие жизненному циклу компонента: created, beforeMount, mounted, beforeUpdate, updated, beforeUnmount и unmounted.
const vColor = {
beforeMount(el, binding) {
el.style.color = binding.value;
},
updated(el, binding) {
el.style.color = binding.value;
}
};Объект binding
Хуки получают объект binding: value, oldValue, arg, modifiers, instance.
<p v-pin:bottom.left="200">Pinned</p>
// binding inside the directive:
// { value: 200, oldValue: ..., arg: 'bottom', modifiers: { left: true } }Реальный пример: v-click-outside
Распространённая директива — вызвать обработчик, когда пользователь щёлкает за пределами элемента.
const vClickOutside = {
mounted(el, binding) {
el._handler = (e) => {
if (!el.contains(e.target)) binding.value(e);
};
document.addEventListener('click', el._handler);
},
unmounted(el) {
document.removeEventListener('click', el._handler);
}
};
// Usage:
<div v-click-outside="closeMenu">...</div>Реальный пример: v-tooltip
Подключите всплывающую подсказку Tippy/Popper с помощью директивы — шаблоны останутся чистыми.
import tippy from 'tippy.js';
const vTooltip = {
mounted(el, binding) {
el._tippy = tippy(el, { content: binding.value });
},
updated(el, binding) {
el._tippy?.setContent(binding.value);
},
unmounted(el) {
el._tippy?.destroy();
}
};v-debounce: ограничение частоты событий ввода
Оберните обработчик @input для ввода в debounce с помощью пользовательской директивы.
const vDebounce = {
mounted(el, binding) {
let timer;
el.addEventListener('input', () => {
clearTimeout(timer);
timer = setTimeout(() => binding.value(el.value), 300);
});
}
};
<input v-debounce="search">Директива, компонент или компонуемая функция
Компонуемые функции: логика с состоянием — данные и ссылки. Компоненты: повторно используемая структура интерфейса со своим шаблоном. Директивы: чистое поведение DOM для уже существующего элемента. Выбирайте директиву, когда шаблон или разметка не нужны.
Вопросы производительности
Директивы выполняются при каждом обновлении. Делайте их малозатратными. Для дорогих операций проверяйте binding.value !== binding.oldValue, чтобы пропускать ненужную работу.
Проверьте себя
В чём разница между использованием директивы Vue и компонента Vue для добавления поведения?
Итоги: пользовательские директивы
Повторно используемая логика DOM с префиксом v-. Регистрируйте директивы локально (константа vName в script setup) или глобально (app.directive). Хуки жизненного цикла: mounted, updated и unmounted. binding предоставляет value, oldValue, arg и modifiers. Используйте директивы для чистого поведения DOM: focus, щелчок за пределами элемента, всплывающая подсказка и debounce. Компоненты предназначены для разметки, компонуемые функции — для логики с состоянием, а директивы — для расширения DOM.
Часто задаваемые вопросы
Урок «Пользовательские директивы» бесплатный?
Да — полный текст урока «Пользовательские директивы» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Frontend Academy, подпишись на CoddyKit PRO. Курс Frontend Academy содержит 4 уроков всего.
Чему я научусь в уроке «Пользовательские директивы»?
Регистрируйте глобальные и локальные директивы с хуками жизненного цикла, такими как mounted и updated, чтобы вынести логику работы с DOM за пределы компонентов Ты практикуешь Frontend Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать Frontend Academy?
Предыдущий опыт не требуется. Frontend Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.
Сколько времени занимает урок «Пользовательские директивы»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке Frontend Academy?
Да. Каждый урок Frontend Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- provide() и inject() для внедрения зависимостей
- Асинхронные компоненты и Suspense
- Пользовательские директивы
- Система плагинов: app.use()