JAVASCRIPT
Creating Custom Directives in Vue 3
Extend Vue 3's functionality by creating custom directives to encapsulate reusable, low-level DOM manipulations, such as auto-focusing elements.
// main.js (or plugin file)
import { createApp } from 'vue';
import App from './App.vue';
const app = createApp(App);
app.directive('focus', {
mounted(el) {
el.focus();
}
});
app.mount('#app');
// App.vue
<template>
<div>
<h1>Custom Directive Example</h1>
<input type="text" v-focus placeholder="I will be focused initially" />
<p>This input automatically gains focus on component mount due to the `v-focus` custom directive.</p>
<button v-tooltip="'This is a helpful tip!'" style="margin-top: 20px;">Hover Me for Tooltip</button>
<p style="margin-top: 10px;">The button above has a custom `v-tooltip` directive, demonstrating more complex DOM manipulation capabilities.</p>
</div>
</template>
<script setup>
// Also define the v-tooltip directive globally (e.g., in main.js)
// app.directive('tooltip', {
// mounted(el, binding) {
// const tooltipEl = document.createElement('div');
// tooltipEl.textContent = binding.value;
// tooltipEl.style.cssText = `
// position: absolute; background: black; color: white; padding: 5px 8px;
// border-radius: 4px; z-index: 1000; font-size: 0.9em;
// bottom: calc(100% + 5px); left: 50%; transform: translateX(-50%);
// white-space: nowrap; pointer-events: none; opacity: 0; transition: opacity 0.3s;
// `;
// el.style.position = 'relative'; // Ensure button is relative for tooltip positioning
// el.addEventListener('mouseenter', () => {
// document.body.appendChild(tooltipEl);
// tooltipEl.style.opacity = '1';
// // Position relative to the element (needs calculation based on body append)
// const rect = el.getBoundingClientRect();
// tooltipEl.style.left = `${rect.left + rect.width / 2}px`;
// tooltipEl.style.top = `${rect.top - tooltipEl.offsetHeight - 5}px`;
// });
// el.addEventListener('mouseleave', () => {
// tooltipEl.style.opacity = '0';
// setTimeout(() => {
// if (tooltipEl.parentNode) {
// tooltipEl.parentNode.removeChild(tooltipEl);
// }
// }, 300); // Allow transition to complete
// });
// el._tooltipEl = tooltipEl; // Store reference
// },
// unmounted(el) {
// if (el._tooltipEl && el._tooltipEl.parentNode) {
// el._tooltipEl.parentNode.removeChild(el._tooltipEl);
// }
// }
// });
// No script needed for directives applied declaratively in template
</script>
<style>
/* Basic styles if needed, but directives often add inline styles */
</style>
How it works: Vue 3 custom directives provide a powerful way to encapsulate reusable, low-level DOM manipulations. They are defined globally or locally and can be applied to elements using the `v-` prefix. This example creates a simple `v-focus` directive that automatically focuses an input element when it's mounted. It also hints at a more complex `v-tooltip` directive (commented out implementation) to illustrate how directives can manage interactive DOM elements, leveraging lifecycle hooks like `mounted` and `unmounted` for precise control.