How to Create Custom Directive in Vue: Simple Guide
In Vue, you create a custom directive by defining an object with lifecycle hooks like
mounted and registering it globally with app.directive() or locally in a component. The directive lets you add custom behavior to DOM elements easily.Syntax
A custom directive in Vue is an object with lifecycle hooks such as mounted, updated, and unmounted. You register it globally using app.directive('name', directiveObject) or locally inside a component's directives option.
Each hook receives the element, binding info, vnode, and prevVNode, allowing you to manipulate the element directly.
javascript
const myDirective = { mounted(el, binding) { // Called when the directive is bound to the element el.style.color = binding.value; }, updated(el, binding) { // Called when the bound value changes el.style.color = binding.value; } }; const app = Vue.createApp({}); app.directive('color', myDirective); app.mount('#app');
Example
This example shows a custom directive v-color that changes the text color of an element based on the value passed to it.
html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0" /> <title>Vue Custom Directive Example</title> <script src="https://unpkg.com/vue@3/dist/vue.global.prod.js"></script> </head> <body> <div id="app"> <p v-color="color">This text changes color using a custom directive.</p> <input type="color" v-model="color" aria-label="Choose text color" /> </div> <script> const colorDirective = { mounted(el, binding) { el.style.color = binding.value; }, updated(el, binding) { el.style.color = binding.value; } }; const app = Vue.createApp({ data() { return { color: '#42b983' }; }, directives: { color: colorDirective } }); app.mount('#app'); </script> </body> </html>
Output
A webpage with a paragraph whose text color changes dynamically as you pick a color from the color input below it.
Common Pitfalls
- Not updating the element style or behavior in the
updatedhook can cause the directive to ignore changes. - Forgetting to register the directive globally or locally will make Vue not recognize it.
- Manipulating the DOM directly without cleanup in
unmountedcan cause memory leaks.
javascript
/* Wrong: Only setting style in mounted, ignoring updates */ const badDirective = { mounted(el, binding) { el.style.backgroundColor = binding.value; } }; /* Right: Also update on value change */ const goodDirective = { mounted(el, binding) { el.style.backgroundColor = binding.value; }, updated(el, binding) { el.style.backgroundColor = binding.value; } };
Quick Reference
Directive Hooks:
created: Called before element insertion.beforeMount: Called before mounting.mounted: Called when element is inserted.beforeUpdate: Called before element updates.updated: Called after element updates.beforeUnmount: Called before element unmounts.unmounted: Called after element unmounts.
Registration: Use app.directive('name', directiveObject) globally or directives: { name: directiveObject } locally.
Key Takeaways
Create custom directives as objects with lifecycle hooks like mounted and updated.
Register directives globally with app.directive or locally inside components.
Always handle updates in the updated hook to reflect changes.
Clean up any DOM changes in the unmounted hook to avoid memory leaks.
Use directives to add reusable DOM behavior simply and clearly.