В Quasar пользовательские директивы позволяют расширять функциональность элементов и компонентов, добавляя к ним специфическое поведение на уровне DOM. Директивы предоставляют механизм для прямого взаимодействия с элементами страницы, аналогичный Vue-директивам, с дополнительными возможностями Quasar, такими как автоматическое управление состоянием компонентов и интеграция с системными событиями.
Директиву в Quasar можно зарегистрировать как глобально, так и
локально для конкретного компонента. Для глобальной регистрации
используется объект конфигурации boot или основной файл
приложения quasar.conf.js. Структура регистрации:
import { boot } from 'quasar/wrappers'
export default boot(({ app }) => {
app.directive('focus', {
mounted(el) {
el.focus()
}
})
})
Ключевые моменты:
mounted(el) — вызывается после добавления элемента в
DOM.el — ссылка на DOM-элемент, к которому применяется
директива.directives:export default {
directives: {
focus: {
mounted(el) {
el.focus()
}
}
}
}
Quasar использует те же жизненные циклы директив, что и Vue 3, с возможностью их расширения:
beforeMount(el, binding, vnode, prevVnode)
— выполняется до вставки элемента в DOM. Полезно для начальной
инициализации.mounted(el, binding, vnode, prevVnode)
— после вставки в DOM. Здесь лучше применять визуальные эффекты и
фокусировку.beforeUpdate(el, binding, vnode, prevVnode)
— до обновления реактивных данных. Можно анализировать изменения
значений.updated(el, binding, vnode, prevVnode)
— после обновления данных. Используется для корректировки состояния
DOM.beforeUnmount(el, binding, vnode, prevVnode)
— перед удалением элемента. Здесь можно освобождать ресурсы,
события.unmounted(el, binding, vnode, prevVnode)
— после удаления элемента. Финальная очистка.Пример с полным набором хуков:
app.directive('highlight', {
beforeMount(el, binding) {
el.style.transition = 'background-color 0.3s'
},
mounted(el, binding) {
el.style.backgroundColor = binding.value || 'yellow'
},
updated(el, binding) {
el.style.backgroundColor = binding.value || 'yellow'
},
unmounted(el) {
el.style.backgroundColor = ''
}
})
Директивы в Quasar поддерживают аргументы и модификаторы, что делает их гибкими:
arg) — позволяет передавать
дополнительную информацию к директиве. Например:app.directive('color', {
mounted(el, binding) {
el.style.color = binding.arg || 'black'
}
})
Использование: <p v-color:red>Текст</p> —
binding.arg вернет 'red'.
modifiers) — булев объект
с ключами, которые позволяют включать/отключать дополнительные
опции:app.directive('padding', {
mounted(el, binding) {
if (binding.modifiers.top) el.style.paddingTop = '10px'
if (binding.modifiers.bottom) el.style.paddingBottom = '10px'
}
})
Использование:
<div v-padding.top.bottom>Контент</div> —
добавляет паддинг сверху и снизу.
binding.value предоставляет возможность передавать
динамические данные в директиву:
app.directive('tooltip', {
mounted(el, binding) {
const tooltipText = binding.value || 'Подсказка'
el.setAttribute('title', tooltipText)
}
})
Использование:
<button v-tooltip="'Нажмите сюда'">Кнопка</button>.
Для сложных сценариев binding.value может быть объектом
с несколькими свойствами, что упрощает управление поведением:
v-tooltip="{ text: 'Сохранить', color: 'blue' }"
Внутри директивы:
const { text, color } = binding.value
el.setAttribute('title', text)
el.style.backgroundColor = color
Директивы идеально подходят для интеграции с библиотеками, которые требуют прямого доступа к DOM, например, для масок ввода или drag-and-drop:
import IMask from 'imask'
app.directive('mask', {
mounted(el, binding) {
el._mask = IMask(el, { mask: binding.value })
},
unmounted(el) {
if (el._mask) el._mask.destroy()
}
})
Использование:
<input v-mask="'0000-0000-0000-0000'"> —
автоматически накладывает маску ввода.
Для динамических эффектов можно привязывать слушатели событий напрямую в директиве:
app.directive('click-outside', {
mounted(el, binding) {
el._handler = event => {
if (!el.contains(event.target)) {
binding.value(event)
}
}
document.addEventListener('click', el._handler)
},
unmounted(el) {
document.removeEventListener('click', el._handler)
}
})
Применение:
<div v-click-outside="handleClose">Меню</div> —
вызовет handleClose при клике вне элемента.
unmounted, чтобы
избежать утечек памяти.binding.value аккуратно, чтобы не вызывать лишние
перерендеры.mounted и минимальные обновления в
updated.Создание пользовательских директив в Quasar позволяет расширять возможности компонентов без изменения их исходного кода, обеспечивая гибкий и чистый подход к манипуляции DOM, работе с событиями и интеграции сторонних библиотек. Правильная структура директив и грамотное использование аргументов, модификаторов и значений делает интерфейс приложения более интерактивным и управляемым.