Custom Directives

Back

Loading concept...

🎨 Vue.js Custom Directives: Teaching Your App New Tricks!

The Magic Wand Analogy πŸͺ„

Imagine you have a magic wand. Every time you wave it at something, that thing does exactly what you tell it to do. Custom directives in Vue.js are just like that magic wand!

When you point your wand (directive) at an element, you give it special powers that Vue doesn’t have built-in.


What Are Custom Directives?

Think about when you learned to ride a bicycle. Someone taught you how to balance, pedal, and steer. Custom directives teach HTML elements new behaviors!

Built-in vs Custom

Vue already has some magic wands:

  • v-if β†’ Makes things appear/disappear
  • v-for β†’ Creates copies of things
  • v-model β†’ Connects form inputs to data

But what if you need your own special power?

// Creating your own magic wand!
const vFocus = {
  mounted(el) {
    el.focus()
  }
}

What happened?

  1. We created a wand called vFocus
  2. When an element appears, it automatically gets focus!

Using Your Magic Wand

<input v-focus />

That’s it! The input box will automatically be ready to type in when the page loads. No clicking needed!


🎭 Directive Hooks: When Does the Magic Happen?

Just like a day has morning, afternoon, and night, an element has different moments in its life. Hooks let you do magic at the perfect moment!

The Element’s Life Story

graph TD A["🌱 Created"] --> B["πŸ”— Mounted"] B --> C["πŸ”„ Updated"] C --> D["πŸ’« Unmounted"]

All The Hooks Explained

Hook When It Happens Real Life Example
created Element is born Baby is born
beforeMount About to appear Getting ready for school
mounted Now visible! Arrived at school
beforeUpdate Data will change About to change clothes
updated Data changed Wearing new clothes
beforeUnmount About to leave Packing bags to go
unmounted Gone! Left the building

Example: Greeting at Every Stage

const vLifecycle = {
  created() {
    console.log("🌱 I'm born!")
  },
  mounted(el) {
    console.log("πŸ‘‹ I can be seen!")
    el.style.color = 'green'
  },
  updated() {
    console.log("πŸ”„ Something changed!")
  },
  unmounted() {
    console.log("πŸ‘‹ Goodbye!")
  }
}

🎁 Directive Hook Arguments: The Magic Ingredients

When you wave your magic wand, you need ingredients to make it work. These arguments are the ingredients!

The Four Magic Ingredients

Every hook receives these helpful friends:

graph LR A["πŸͺ„ Hook Called"] --> B["el: The Element"] A --> C["binding: The Instructions"] A --> D[vnode: Vue's Blueprint] A --> E["prevVnode: Old Blueprint"]

1. el - The Element Itself

This is the actual HTML element you’re pointing at.

const vColor = {
  mounted(el) {
    // el IS the element!
    el.style.backgroundColor = 'yellow'
  }
}

2. binding - The Instructions

This object tells you WHAT the user wants:

const vColor = {
  mounted(el, binding) {
    // binding.value = what user passed
    el.style.color = binding.value
  }
}
<p v-color="'red'">I'm red!</p>
<p v-color="'blue'">I'm blue!</p>

Inside the binding Object

Property What It Means Example
value Current value 'red'
oldValue Previous value 'blue'
arg After the colon v-color:bg β†’ 'bg'
modifiers After dots v-color.bold β†’ {bold: true}
instance Component using it The Vue component
dir The directive object The whole directive

Complete Example with All Parts

const vHighlight = {
  mounted(el, binding) {
    // binding.value = the color
    // binding.arg = where to apply
    // binding.modifiers = extra options

    const color = binding.value || 'yellow'
    const target = binding.arg || 'background'

    if (target === 'background') {
      el.style.backgroundColor = color
    } else {
      el.style.color = color
    }

    if (binding.modifiers.bold) {
      el.style.fontWeight = 'bold'
    }
  }
}
<!-- Yellow background -->
<p v-highlight>Hello!</p>

<!-- Red text -->
<p v-highlight:text="'red'">Red text!</p>

<!-- Blue background, bold -->
<p v-highlight.bold="'blue'">Bold blue!</p>

3. vnode - Vue’s Blueprint

This is Vue’s internal representation. You rarely need it, but it’s there!

mounted(el, binding, vnode) {
  console.log(vnode.type) // Element type
}

4. prevVnode - The Old Blueprint

Only available in updated and beforeUpdate. Shows what it looked like before.

updated(el, binding, vnode, prevVnode) {
  console.log('Changed from:', prevVnode)
  console.log('Changed to:', vnode)
}

🏠 Registering Your Directives

Local Registration (One Component)

export default {
  directives: {
    focus: vFocus,
    color: vColor
  }
}

Global Registration (Everywhere!)

const app = createApp(App)
app.directive('focus', vFocus)
app.directive('color', vColor)
app.mount('#app')

🎯 Real-World Example: Auto-Resize Textarea

Let’s build something useful! A textarea that grows as you type.

const vAutoResize = {
  mounted(el) {
    el.style.overflow = 'hidden'
    el.style.resize = 'none'

    const resize = () => {
      el.style.height = 'auto'
      el.style.height = el.scrollHeight + 'px'
    }

    el.addEventListener('input', resize)
    resize() // Initial resize
  }
}
<textarea v-auto-resize>
  Type here and watch me grow!
</textarea>

πŸ’‘ Quick Summary

Concept What It Does
Custom Directive Teaches elements new tricks
Hooks When the magic happens
el The element to modify
binding What the user wants
value The passed data
arg Extra instruction after :
modifiers Options after .

πŸš€ You Did It!

You now know how to:

  • βœ… Create your own custom directives
  • βœ… Use hooks to control timing
  • βœ… Access all the magic ingredients
  • βœ… Build real, useful features

Custom directives are your secret superpower. Use them to make your Vue apps do exactly what you imagine! πŸŽ‰

Loading story...

Story - Premium Content

Please sign in to view this story and start learning.

Upgrade to Premium to unlock full access to all stories.

Stay Tuned!

Story is coming soon.

Story Preview

Story - Premium Content

Please sign in to view this concept and start learning.

Upgrade to Premium to unlock full access to all content.