Custom Directives in Vue.js

Nowadays, VueJs development service providers prefer to use custom directives to manipulate DOM elements in the software solutions they are creating. These directives enable them to make the code easier and cleaner to read and reuse whenever required. And as Vue comes with the ability to create custom directives, it is more popular than other JavaScript frameworks. In this blog, we will learn about Vue directives, go through some of the most popular Vue directives that every VueJs development company uses, and see how a developer can create a custom directive in VueJs.

1. What is a Vue Directive?

VueJs developers utilize Vue directives as the most special attributes to make the application interact with the DOM. To make it more simple, when a developer uses the Vue directive it applies modifications to the DOM, and some of its optional properties help in defining possible side effects. Vue directive comes with a v- prefix. For instance, v-show, v-if, v-else, and v-model.

2. Built-in Directives in VueJs

Here we will have a look at some of the most popular and widely used built-in Vue directives-

2.1 v-if, v-else and v-else-if directives

The v-if, v-else, and v-else-if are those directives that allow the VueJs developer to create HTML elements that are conditionally rendered and these same elements will work similarly to JavaScript conditions known as if, else, and else if. 

Unlike JavaScript where the developers will have to return HTML or code, Vue will enable developers to conditionally render a specific block of code. To apply the Vue directive, the technology expert will have to add it to an HTML element. Developers can specifically perform this action within the template section of the Vue single-file component.

For instance, if the developer wants to add a v-if directive to a span element, the following syntax can be used –

<span v-if="condition"></span>

Here, the condition acts as a placeholder for the boolean expression determining whether the paragraph element will render or not.

Below is the code that specifies how v-if directives work in a real situation:

<template>
  <p v-if="emp.name">
    Hola, {{ emp.firstName }}!
  </p>
  <p v-else-if="emp.username">
    Hola, {{ emp.username }}!
  </p>
  <div v-else>
    <button>Employee Login</button>
    <button>Sign Up</button>
  </div>
</template>
<script setup>
const emp = {
    name: 'Samay Patel',
 
    username: 'samayP',
    contact: 987654321
  }
</script>

In the above code, there are many HTML elements like <div> and <p> tags along with two buttons. Here, when the code runs on the web browser, only a chunk of data from all gets rendered as per the condition specified by the developer and its value. When the value of the condition is true it gets rendered and the false HTML conditions will not be able to render in DOM (Document Object Model).

Here, in this code, as name has its value in the <script> tag, the expression emp.name will be true. This means that the web browser will render the paragraph and the output will be as shown in the below image.

emp.name

If the value of the script tag is not specified by the emp, the condition will be false and Vue will move to the v-else-if directive. And in this example, the V-else-if directive is attached to the emp.username expression, if the condition comes true, the paragraph will be rendered. In this case, the system will have to delete the firstName in the <script> tag for which the following syntax can be used. 

<script setup>
const emp = {
 
    username: 'samayP'
  }
</script>

In the above code, as we can see the condition emp.name has been false, but  emp.username condition is true, the username will be rendered as shown in the below image.

emp.username

Now, the last probability is that all the conditions get false, and then the control will get passed to the v-else directive. In the v-else directive, there are two buttons to log in or create an account which needs to be rendered. In this case, first, the username data will have to be deleted in the script element as shown in the below syntax:

<script setup>
const emp = {
    lastName: 'Patel',
  }
</script>

After the last probable conditioning, the output will display default buttons rendered in the browser, as illustrated in the image below.

default buttons

After having a look at all the probabilities and seeing how all the three v-if, v-else, and v-else-if works, it is clear that the application code written by the Vue developer must have a v-if directive directly before a v-else or v-else-if directive. If not, then the code will not let the application run.

For instance, in the below code, you can see the invalid syntax as per the wrong placement of the condition.

<template>
  <p v-if="emp.name">
    Hola, {{ emp.name }}!
  </p>
  <p v-else-if="emp.username">
    Hola, {{ emp.username }}!
  </p>
  <h1>Heading</h1>
  <div v-else>
    <button>EmployeeLogin</button>
    <button>Sign Up</button>
  </div>
</template>
<script setup>
const emp = {
    name: 'Samay Patel',
 
    username: 'samayP'
  }
</script>

In the above code, as the <h1> element after the paragraph has no other directive before the v-else-if directive, the code will fail to render. The output of the code  will be as below:

OutputSyntaxError: v-else/v-else-if has no adjacent v-if.

2.2 v-for

Another directive that we will learn about is v-for. It is a built-in directive in Vue.js. This directive enables the developers to loop via an array of items and then render each item into a template. Below is an example of the same:

<template>
  <ul>
    <li v-for="product in products" :key="product.id">
      {{ item.text }}
    </li>
  </ul>
</template>
<script>
export default {
  data() {
    return {
      products: [
        { id: 1, text: laddoo' },
        { id: 2, text: 'jalebi' },
        { id: 3, text: 'gulab jamun' }
      ]
    }
  }
}
</script>

Here in the above code, we saw that the developer has used the v-for directive to loop through the items array. After that, each item is rendered as the items are in an unordered list. In this syntax, the :key attribute is used which offers a unique identifier for each item. The output of the above example will be as below:

  • Laddoo
  • Jalebi
  • Gulab Jamun

2.3 v-show

Developers commonly use the v-show VueJS directive to show or hide elements within the application. It is similar to a toggle button where you want to show or hide something to the users as per the condition. The v-show directive can be considered as an if-else condition of JavaScript. Here, if the condition is fulfilled the action will be performed and if not, only the action that is present by default will be performed. Here is the code for the same:

<template>
 <div>
  <h1>{{ message }}</h1>
  <div v-show="isVisible">
   <h1>This is a v-show Example</h1>
  </div>
 </div>
</template>
<script>
export default {
name: "VShowExample",
data() {
 return {
  isVisible: true,
  message: "This is an example of v-show Directive in VueJs"
 };
}
};
</script>

In the above blog, the developer has used a boolean flag “isVisible” whose default value is set to true. This means that as per the flag value, the div element will be displayed and hidden.

v-show directive

2.4 v-html

Another Vue directive on our list is v-html. Developers widely use this directive to convert HTML contained within a string literal into raw HTML for users to read in the browser. It enables the developers to flexibly create and apply conditions on the HTML. For instance, in this below code, the <div> tag has a v-html directive with value as data property:

<template>
  <div v-html="htmlCode" />
</template>
<script setup>
  const htmlCode = `<p><span>HTML</span> is present in this string</p>`
</script>

Here, the v-html directive sends a message to Vue.js to inject the string of the someHtmlCode data. After Vue compiles it, the DOM will look like below:

<div>
  <p><span>HTML</span> is present in this string</p>
</div>

This will also get rendered in the browser as shown in the below image.

v-html directive sends a message

Basically, this directive is used when the developer wants to render HTML that comes from a REST API service.

2.5 v-bind

In our list of Vue directives, the next one is the v-bind directive. It is a directive that is used by developers when they have to bind the values of an HTML attribute with a data property. V-bind directive helps in creating one-way data binding, which means that when changes are made in the data property of the application code, it will automatically update the HTML attribute value. But vice versa isn’t possible. Here is an example of the same:

<template>
  <div>
    <img v-bind:src="imageSource">
  </div>
</template>
<script>
export default {
  data() {
    return {
      imageSource: 'https://fastly.picsum.photos/id/431/200/200.jpg'
    }
  }
}
</script>

In the above source code, the “imageSource ” data property and the “src” attribute are bound together via a v-bind directive. This means that when the value of the “imageSource” data property changes, it will also change the value of the “src” attribute and will update the image that has been displayed.

The v-on directive is also a valuable Vue.js directive. It is used by the developer when they want to attach event listeners to DOM elements. This directive aims to bind JavaScript event handlers to DOM events. Here is an example of the same:

<template>
  <div>
    <button v-on:click="incrementCounter">Click here!</button>
    <p>I have been clicked {{ counter }} times.</p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      counter: 0
    };
  },
  methods: {
    increaseCounter() {
      this.counter++;
    }
  }
};
</script>

Here, in this code, the v-on:click directive is used to make it listen to the click event on the button element. When this button is clicked, the directive will trigger the incrementCounter method. To write the v-on directive @ abbreviation is used as shown in the below code:

<button @click="increaseCounter">{{ counter }}</button>

Besides this, v-on can also be used to listen to multiple events, here is an example of the same: 

<template>
  <input
    v-on="{ input: setValue, focus: focusEvent, blur: blurEvent }"      
  />
</template>
<script>
export default {
  data() {
    return {
      value: ''
    };
  },
  methods: {
    setValue(event) {
      this.value = event.target.value;
    },
    focusEvent() {
      console.log('Focus event');
    },
    blurEvent() {
      console.log('Blur event');
    }
  }
};
</script>

The above Vue code specifies that the v-on directive attaches multiple event listeners to a single input element. Developers have used the input event listener, to update the value data property while the blue and focus event listeners are used to log the messages to the console.

2.6 v-model

Another Vue directive that is widely used is the v-model directive. It helps in binding the input element values to a data property in the Vue instance. This directive helps developers to create a two-way data binding, which means that whenever changes are made in the input element, those changes will automatically be reflected on the data property and vice versa is also possible. Below is an example for the same:

<template>
  <div>
    <input v-model="message">
    <p>{{ message }}</p>
  </div>
</template>
<script>
export default {
  data() {
    return {
      message: 'This is the message!'
    }
  }
}
</script>

In the above code, developers have used the “message” data property which is bound to the input element value. This data property will be displayed in a paragraph after the input element. So now, when changes are made in the input value by the users, it will be reflected in the “message” data property. This change will also be seen in the paragraph and vice versa. 

In addition to this, the developers can also make use of the v-model with other input elements, like radio buttons and checkboxes in order to bind the input element value with the data property as shown in the below code:

<template>
  <input type="checkbox" v-model="isChecked" />
  <span v-if="isChecked">Checked</span>
  <span v-else>Not checked</span>
</template>
<script>
export default {
  data() {
    return {
      isChecked: false
    };
  }
};
</script>

The above code specifies that the v-model directive is used to bind the checkbox value to the isChecked data property. This means that when any action is performed on the checkbox, the isChecked data property will get updated, and it will be displayed accordingly.

2.7 v-once

The v-once is also a Vue.js directive. Vue developers use this directive when they want to specify that a component should render its content only once which cannot be changed even after changes are seen in the data. Below is an example of the same:

<template>
  <div v-once>{{ message }}</div>
</template>
<script>
export default {
  data () {
    return {
      message: 'This will be displayed once!'
    }
  }
}
</script>

The v-once code has used the message “This will be displayed once!”. This message will be displayed once and it won’t get updated even after the data gets changed.

Comment
byu/minireset from discussion
invuejs

2.8 v-memo

v-memo is a directive that is used by the developer to memorize a subtree of a component. This is in relation to a fixed set of dependency values. This means that the sub-tree will delay changes till there is a change in one of the dependencies. Here is an example of the same:

<template>
  <div>
    component data
    <div v-memo="[customValue]">
      <svg >
        <title>{{ CustomValue }}</title>
        ...
      </svg>
      <vue-custom-element :value="customValue" />
    </div>
  </div>
</template>

In the above code, the sub-tree is created to display the value of the component and will display its changes till the dependency is updated.

3. How to Build Custom VueJs Directives?

Custom directive definition objects can provide hook functions. Here will go through the steps that will help us to create custom VueJS directives:

3.1 Using Hook Functions

The very first thing is to use hook functions. These help the developer to customize and offer the needed functionality for the directive at specific life cycle stages. Here are the five hook functions that are available with Vue:

  • inserted
  • bind
  • update
  • componentUpdate
  • unbind

inserted

This hook is called when the developer wants to insert an underlying element into the parent node. This means that the context of the hook is part of the tree of nodes and not the live DOM.

bind

The bind function hook is called when the Vue directive is bound to the underlying element.

update

The update hook function is called by the developer in the code once the component’s VNode has been updated.

componentUpdate

This function can be called after containing component’s VNode.  

unbind

This hook function is called one time when the element and directive is unbound from each other.

3.2 Binding Function Parameters

Every hook function receives the same set of input parameters defined as follows.

el

This parameter represents the element of the application where the developer will apply custom directives. You can apply the directive to any valid HTML element.

binding

It is an input parameter where the binding object contains the below-given properties:

  • name: The directive name without the v- prefix. This means that if you are using a custom directives called v-focus, it specifies that the directive name is focus.
  • expression: Here the binding JavaScript expression is represented as a string literal.
  • value: It means the value that is passed to the custom directive. For example, in the v-slot=”prop” directive, the value is prop.
  • oldValue: This binding property is available inside hook functions like update() and componentUpdate(). It holds the value of the previous directive.
  • arg: It is a property that represents the arguments passed by the Vue developer to the directive.

vnode

Vue compiler produces a virtual node.

oldVnode

It means the previous virtual node will only be available in functional hooks like the update() and componentUpdated().

3.3 Building a Custom Directive

Vue empowers software development teams to create additional directives, offering a unique avenue for customized functionality. The custom directive in Vue can manipulate elements and can also handle the reactivity in the DOM. With the help of custom directives, you can fulfill your application’s requirements. Even some of the Vue plugins use custom directives pretty.

These custom directives provide several hook functions :

  • bind – It is a hook that is called once when the directive is bound to an element of the application.
  • unbind – It is called once when the directive is unbound from an element of the application.
  • inserted – This hook is used when there is a need to insert a bound element into its parent node.
  • update – It is used to update the child elements.
  • componentUpdated – It is used after the children elements have been updated.

4. Conclusion

In this blog, we got an overall idea about Vue directives, went through some of the most widely used custom directives in Vue, and saw how to use them. The most common but useful built-in directives we learned about here are v-if, v-show, v-on, and v-html. Besides this, you also learned how to create custom directives. These directives can play a vital role in building a code for any application and running that solution smoothly.

FAQs

What is the Purpose of Directives in Vue?

The main purpose of directives being reusable chunks of code is to enable the developers to manipulate HTML in different ways like connecting events to an element, conditionally rendering an element, and creating dynamic attributes.

What is the Difference Between Bind and Insert in the Vue Directive?

In Vue directives, developers call the bind function only once during the initial binding of a directive to the element. They invoke the insert function when they intend to insert the bound element into its parent node.

What is the Difference Between Directive and Component in Vue?

In VueJS, developers use directives to modify the behavior of various sections of HTML, while components, referred to as widgets, represent these sections within the HTML.

How Many Types of Directives are There in Vue JS?

Some of the most common types of directives in VueJS are v-if, v-for, and v-model.

profile-image
Itesh Sharma

Itesh Sharma is core member of Sales Department at TatvaSoft. He has got more than 6 years of experience in handling the task related to Customer Management and Project Management. Apart from his profession he also has keen interest in sharing the insight on different methodologies of software development.

Comments

  • Leave a message...