loading...
Cover image for Vue.js custom directives with examples. ↘

Vue.js custom directives with examples. ↘

vaibhavkhulbe profile image Vaibhav Khulbe ・5 min read

After making some custom components, it's time to learn a bit about custom directives. There are some really helpful and awesome ones built-in Vue, but heck yes, we can create our own custom ones. This article will show you how to do this with examples.


Example GIF

Exactly this!

What are directives in Vue? 🤔

As per its documentation,

"A directive is some special token in the markup that tells the library to do some changes to a DOM element."

Let's make the above sentence better. You see, when we write HTML, we start with a tag (<h1>), then close it (</h1>). In between the tag, we add what we want to display (Hello World!) and when we want to add some styling to this, we use some attributes like style.

<h1 style="color: grey;">Hello World!</h1> 

Something similar can be applied to Vue's template markup. A Vue.js directive can only appear in the form of a prefixed HTML attribute that takes the following format:

<div v-text="message"></div>

In this case, v-text is a directive of the div element. Here are some other examples:

<!-- Example format with custom element -->
<element
  prefix-directiveId="[argument:] expression [| filters...]">
</element>

<!-- Example with inline expressions -->
<div v-text="'hello ' + user.firstName + ' ' + user.lastName"></div>

<!-- Example with an argument -->
<div v-on="click : clickHandler"></div>

Vue already got some nifty core directives like v-model and v-show, but it doesn't stop you to make custom ones!

How to make custom directives? 🧐

Before we make it, let's see its syntax or examples. There are two ways you can register them:

Registering globally: Want to make a custom directive which automatically focuses an input field when someone opens up your web app?

Vue.directive('custom-directive-name', {
  inserted: function (el) {
    // Add code to focus the input field
  }
})

Here's how we'll use the above directive in our app template:

<app-input custom-directive-name></app-input>

Let's break-down the new things you see above:

  • The Vue.directive is used to register or retrieve a global directive.

  • The inserted is a Hook function which is called when the element to bound has been 'inserted' into its parent node.

Hook functions are some of the default (but optional) functions provided by Vue over directives. The one hook function in which we are interested in is the bind function. It's called when the directive is first bound to the element.

Each of these functions has three additional arguments:

  • el: the 'element' on which the binding sits.
  • binding: the object which contains the arguments that are passed into the hooks.
  • vnode: this allows us to directly refer the virtual DOM.

Registering locally: If one of your components needs a custom directive then you can seamlessly register it under the <script> tag (for local) or inside your main.js (for global) file as follows:

directives: {
  custom-directive-name: {
    // directive definition
    inserted: function (el) {
      // Add code for the directive
    }
  }
}

Okay, let's get serious and build one from scratch. For demo purposes, we'll make a custom directive which simply changes the text colour of a heading.

Step 1: Register the global directive

Open up the main.js file in your newly created Vue project. Start by declaring the custom directive. Note that you should define all of your global directives before the Vue's instance creation code.

Let's name our custom directive as colorChange. Inside this, we'll access the provided bind hook function passing in both the el and binding arguments.

Vue.directive("colorChange", {
  bind(el, binding) {
    // Code to change the text color dynamically 
  }
});

So, how do we change the color? Here, both the el and binding arguments come into play. We pick the element we want to change using el, over it we set the style property to be color through which we change color in CSS. Then, we set this value to be equal to the value stored in the binding i.e our element!

Now, our code updates like this:

Vue.directive("colorChange", {
  bind(el, binding) {
    el.style.color = binding.value;
  }
});

Step 2: Use the new directive

Open any of your component where you need this functionality, where there is a heading (<h1>) or just a text (<p>) in the template, simply add the newly created colorChange custom directive. Pass in any color value in the String format.

Note that all custom/local directives in Vue start with v-. Here's an example of how to use this:

<div>
    <h1>Custom Directives</h1>

    <h1 v-colorChange="'red'">
    This is a custom directive RED text</h1>

    <h2 v-colorChange="'#f2652f'">
    This is a custom directive TOMATO text</h2>

    <p v-colorChange="'dodgerblue'">
    This is a custom directive DODGERBLUE text</p>
</div>

Notice how you can pass both the CSS color names and the hex values also!

This is what you’ll see in the output window:

Custom directive output

Where to next? 🤔

Make the above directive more powerful by adding an option for the user to manually choose a color or play with other properties provided by Vue. The following resources might help:


Thanks for reading, I appreciate it! Have a good day. (✿◕‿◕✿)



📫 Subscribe to my weekly developer newsletter 📫

PS: From this year, I've decided to write here on DEV Community. Previously, I wrote on Medium. If anyone wants to take a look at my articles, here's my Medium profile.

Discussion

pic
Editor guide