Categories
JavaScript Vue

Introduction to Vue.js Directives

Spread the love

Vue.js is an easy to use web app framework that we can use to develop interactive front end apps.

In this article, we’ll look at how to manipulate the DOM with Vue.js directives.

Basics

Vue lets us register or own custom directives, in addition to using built-in ones like v-for and v-if .

It’s useful for low-level DOM manipulation that can’t easily be done with components.

For example, we can make one as follows:

src/index.js :

Vue.directive("focus", {  
  inserted(el) {  
    el.focus();  
  }  
});
const vm = new Vue({  
  el: "#app"  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <input v-focus />  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

In the code above, we defined the focus directive, which is referenced by adding a v- prefix to it.

The focus directive calls focus on the DOM element when it’s inserted into the DOM. The inserted method is a hook that handles the situation when the element that has the directive applied is inserted into the DOM.

The el parameter has the DOM element, which is why we can call the focus method on it.

Therefore, when we load the page, we’ll see that the input element is focused. This is the work of the focus directive.

The code above registered the directive globally. We can also register the directive locally as follows:

src/index.js :

const focus = {  
  inserted(el) {  
    el.focus();  
  }  
};

const vm = new Vue({  
  el: "#app",  
  directives: {  
    focus  
  }  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <input v-focus />  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

The focus directive will then only be available to the component that it’s registered in.

Hook Functions

A directive can have the following hook functions. They’re all optional.

  • bind — called only once when the directive is first bound to the element. It’s used for one-time setup work
  • inserted — called when the bound element is inserted into its parent node. It guarantees the parent node presence.
  • updarted — calls after the containing component VNode has updated but possibly before children have updated. VNode is a node in the virtual DOM, it stands for virtual node.
  • componentUpdated — called when the containing component’s VNode and VNodes of its children are updated
  • unbind — called only once when the directive is unbound from the element

Directive Hook Arguments

The hooks above take the following arguments:

el

The element the directive is bound to. It can used to manipulate the DOM

binding

An object containing the following properties:

  • name — name of the directive without the v- prefix
  • value — value passed to the directive. For example, if we have v-foo='1' then the value is 1 .
  • oldValue — the previous value. This is only available in update and compoentUpdated . It’s available whether or not the value has changed.
  • expression — the expression of the binding as a string. For example, if we have v-foo='1 + 2' then it’s 1 + 2 .
  • arg —the argument passed into the directive. For example, if we have v-foo:bar then the arg is ‘bar‘.
  • modifiers — an object with modifiers. If we have v-foo.bar.baz then it would be { bae: true, baz: true } .

Everything other than el are read-only.

For example, we can display the data that are passed from the parameters as follows:

src/index.js :

const foo = {  
  inserted(el, binding, vnode) {  
    const stringify = JSON.stringify;  
    el.innerHTML = `  
      name:   
        ${stringify(binding.name)}  
      <br>  
      value:    
       ${stringify(binding.value)}  
      <br>  
      expression:  
        ${stringify(binding.expression)}  
      <br>  
      argument  
       ${stringify(binding.arg)}  
      <br>  
      modifiers:  
        ${stringify(binding.modifiers)}  
      <br>  
      vnode keys:  
       ${Object.keys(vnode).join(", ")}`;  
  }  
};

const vm = new Vue({  
  el: "#app",  
  directives: {  
    foo  
  }  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>  
  </head>  
  <body>  
    <div id="app">  
      <div v-foo:bar.baz="1 + 2"></div>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then we get:

name: "foo"  
value: 3  
expression: "1 + 2"  
argument "bar"  
modifiers: {"baz":true}  
vnode keys: tag, data, children, text, elm, ns, context, fnContext, fnOptions, fnScopeId, key, componentOptions, componentInstance, parent, raw, isStatic, isRootInsert, isComment, isCloned, isOnce, asyncFactory, asyncMeta, isAsyncPlaceholder

Conclusion

We can define our own Vue directives to manipulate DOM elements by binding them to specific DOM elements and then run the elements’ methods.

It works by running hooks when certain during certain stages of virtual node manipulation by Vue.

The hooks take the DOM element object as the first argument and a binding object which has the data about the directive like name, the value passed in, modifiers and arguments.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *