Vue.js: Built-in and Custom Directives - An Overview

Directives are classes that add additional behavior to HTML elements. If you are familiar with Angular, you might have encountered directives like ngModel, ngClass, etc. In Vue, these are v-model, v-text, and many more.

In this post, we will go through some of these directives and create a simple custom directive of our own.

Built-in Directives

Directives used for rendering

  • v-text: This expects a string and renders it as is.
  • v-html: It expects a string. HTML tags in the string are processed.
  • v-pre: It skips the compilation of the content and preserves Vue syntax.
  • v-once: It treats the component as static, renders it once, and omits future updates.
  • v-cloak: Hides un-compiled template, i.e., raw mustache tag, till it is ready.

A list of directives used for conditional rendering are:

  • v-show: Affects the display CSS property of the component. Passed value can be any (string, function, boolean).
  • v-if: If truthy, render the element's content; otherwise, do not. The value passed can be any.
  • v-else: It does not need any value and is used in conjunction with v-if and v-else-if block.
  • v-else-if: Passed value can be any. A v-if block should precede it.

Directive for rendering a list of items:

  • v-for: It behaves just like a for loop and expects an Array, Object, number, string, or an Iterable.

Other directives ( v-model, v-on, v-bind, v-memo, v-slot) are not covered here because they require a detailed post for themselves.

Below is a demo for all the directives listed above.

Custom Directives

A custom directive is an object containing life cycle hooks. The hooks receive the element el to which it is bound. For example, we want to focus on an input field when mounted.

    <input v-focus placeholder="Focus on mount" />

const focus = {
    mounted: (el) => el.focus();

export default {

The above example is limited to the component.

If we want to use custom directives throughout our project, we need to register the directive globally, i.e., at the app level.

const app = createApp({})

// make v-logtarget usable in all components
app.directive("logtarget", {
  mounted: (el, binding, vnode) => console.log(el, binding, vnode)
    <!-- Logs el on console -->
    <h4 v-logtarget>Check console.</h4>

Directive hooks

Just like components, directives have lifecycle methods as well.

const focus = {
  // called before bound element's attributes or event listeners are applied
  created(el, binding, vnode) {
    // vnode is virtual DOM node

  // called right before the element is inserted into the DOM.
  beforeMount(el, binding, vnode) {},

  // called when the bound element's parent component and all its children are mounted.
  mounted(el, binding, vnode) {},

  // called before the parent component is updated
  beforeUpdate(el, binding, vnode, prevNode) {},

  // called after the parent component and all of its children have updated
  updated(el, binding, vnode, prevNode) {},

  // gets called before the parent component is unmounted
  beforeUnmount(el, binding, vnode) {},

  // called when the parent component is unmounted
  unmounted(el, binding, vnode) {},

To read more about hook arguments, visit here.

Note: The use of custom directives on components is not recommended. The hook arguments listed above, apart from el, are read-only and should never be modified.

Stay tuned for more Vue.js blogs!

Divyajyoti Ukirde

Divyajyoti Ukirde

Senior Software Engineer | Investing in knowledge | with Passion for building stuff