DEV Community

Cover image for Christmas guide to Custom Directives in Vue 🎄
Jakub Andrzejewski
Jakub Andrzejewski

Posted on

Christmas guide to Custom Directives in Vue 🎄

Vue.js, one of the most popular JavaScript frameworks, offers developers powerful tools to build user interfaces efficiently. Among its many features, directives stand out as a means to directly manipulate the DOM.

While Vue provides a suite of built-in directives like v-if, v-for, and v-model, there are times when you need to implement functionality that isn’t covered by these defaults. This is where custom directives come into play. In Vue 3, the API for creating custom directives remains intuitive yet powerful.

This festive article explores what custom directives are, how to create them, and when to use them—all with a sprinkle of holiday cheer!

Enjoy!

🤔 What Are Directives in Vue?

Directives in Vue are special markers in the DOM that extend HTML’s capabilities. They allow you to bind dynamic behavior to elements declaratively. For example, the v-if directive conditionally renders an element, and v-bind dynamically binds an attribute to an expression.

Custom directives enable developers to encapsulate reusable DOM-manipulation logic, making your code more modular and maintainable.

Vue 3 custom directives provide several lifecycle hooks that correspond to different stages of a directive’s lifecycle:

  • created(el, binding, vnode, prevVnode): Called once when the directive is bound to the element.
  • beforeMount(el, binding, vnode, prevVnode): Called before the element is inserted into the DOM.
  • mounted(el, binding, vnode, prevVnode): Called when the element is inserted into the DOM.
  • beforeUpdate(el, binding, vnode, prevVnode): Called before the element’s containing component is updated.
  • updated(el, binding, vnode, prevVnode): Called after the element’s containing component and children are updated.
  • beforeUnmount(el, binding, vnode, prevVnode): Called before the directive’s element is unmounted.
  • unmounted(el, binding, vnode, prevVnode): Called after the directive’s element is unmounted.

Each hook provides access to the directive’s binding object, which contains useful properties like:

  • value: The current value of the directive.
  • oldValue: The previous value.
  • arg: An argument passed to the directive (e.g., v-my-directive:arg).
  • modifiers: An object of modifiers (e.g., v-my-directive.mod1.mod2).

🟢 Creating custom directives in Vue

In Vue 3, you can register custom directives either globally or locally.

To register a directive globally, use the app.directive method:

import { createApp } from 'vue';
import App from './App.vue';

const app = createApp(App);

app.directive('focus', {
  // Hook to handle when the directive is bound to the element
  mounted(el) {
    el.focus();
  }
});

app.mount('#app');
Enter fullscreen mode Exit fullscreen mode

In this example, the v-focus directive focuses the input element whenever it is mounted to the DOM.

For local registration, you define the directive within the directives option of a component:

export default {
  directives: {
    focus: {
      mounted(el) {
        el.focus();
      }
    }
  },
  template: `<input v-focus />`
};
Enter fullscreen mode Exit fullscreen mode

Custom directives shine in scenarios that require direct DOM manipulation, especially when such logic doesn’t belong in components or composables. Let's take a look at the following example of a directive to add a snowflake effect on hover:

app.directive('hover-snow', {
  mounted(el) {
    el.addEventListener('mouseenter', () => {
      el.style.backgroundImage = 'url(https://example.com/snowflake.png)';
      el.style.backgroundRepeat = 'no-repeat';
      el.style.backgroundPosition = 'center';
    });
    el.addEventListener('mouseleave', () => {
      el.style.backgroundImage = '';
    });
  },
  unmounted(el) {
    el.removeEventListener('mouseenter');
    el.removeEventListener('mouseleave');
  }
});
Enter fullscreen mode Exit fullscreen mode

This directive sprinkles your elements with snowflakes, adding a touch of Christmas magic to your app.

Custom directives are ideal when:

  1. Direct DOM Manipulation is Needed: For operations like focusing elements or integrating third-party libraries.
  2. Reusability is Required: Encapsulate common DOM logic into a directive for consistency across components.
  3. Avoiding Component Overhead: Use directives instead of components for simple DOM-related behavior, reducing boilerplate.

However, for more complex or state-driven logic, consider using composables or Vue components instead, as they integrate more naturally into Vue’s reactive system.

📖 Learn more

If you would like to learn more about Vue, Nuxt, JavaScript or other useful technologies, checkout VueSchool by clicking this link or by clicking the image below:

Vue School Link

It covers most important concepts while building modern Vue or Nuxt applications that can help you in your daily work or side projects 😉

✅ Summary

Well done! Vue 3’s custom directives provide a concise way to encapsulate and reuse DOM manipulation logic. They complement Vue’s declarative programming paradigm, enabling developers to handle edge cases and extend functionality effortlessly. By understanding how and when to use them, you can enhance your applications with clean and maintainable code.

Take care and see you next time! And Merry Christmas! 🎄

And happy coding as always 🖥️

Top comments (0)