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.
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:
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. (✿◕‿◕✿)
*looks in library* yup, this is the @MicrosoftLearn course you'll want: https://t.co/0HgRg92sUR
— Microsoft Developer UK (@msdevUK) September 14, 2020
Image source: https://t.co/5T0ByA8nyV#DevHumour #Python #Developer pic.twitter.com/zLWryaiPQ6
Top comments (2)
So custom direcitves only work on DOM elements, but not on components?
They do work on components. Check this in docs.