Vue.js Directives: Data Binding in Vue
Tags: vue, javascript, beginners, webdev
Published: 2022-10-08 13:42:51

---
title: Vue.js Directives: Data Binding in Vue
published: true
description: Introduction to the Vue.js directives, examining the concept and observing some examples.
tags: vue, javascript, beginners, webdev
cover_image: https://dev-to-uploads.s3.amazonaws.com/uploads/articles/c2qdfrirvq1wxz2zhkyp.png
series: A beginner's guide to Vue.js
canonical_url: https://vuenoob.com/posts/vuejs-directives-data-binding-in-vuejs/
---

Making the front-end dynamic in web development involves logic that reorganizes or rewrites various nodes of the HTML DOM tree. In simple terms, the HTML in our pages needs to be updated or changed without triggering page reloads.

In Vue.js, this is made possible by directly binding the target HTML tag's inner content, attributes, and events to the Vue.js instance with the help of its custom directives.

These Vue.js directives help us apply JavaScript operations directly on the template HTML while Vue.js handles the nitty-gritty work we'd normally do in vanilla JavaScript under the hood, simplifying the whole development process for us.

## Custom Vue.js Directives

Vue.js has a number of these custom directives that assist us in making the HTML markup in our templates dynamic. Let's get acquainted to some of them through simple demonstrations.

Take a look at the following example.

```html
<html>
  <style>
    .box {
      background-color: coral;
      width: 100px;
      height: 100px;
      margin: 20px;
    }
  </style>
  <div id="app">
    <div class="box" v-show="showBox"></div>
  </div>
  <script src="https://unpkg.com/vue@3"></script>
  <script>
    let app = Vue.createApp({
      data() {
        return {
          showBox: true,
        };
      },
      mounted() {
        const toggleVisibility = () => {
          this.showBox = !this.showBox;
        };
        let intervalId = setInterval(toggleVisibility, 1000);
        const stopToggle = () => {
          this.showBox = true;
          clearInterval(intervalId);
        };
        let timeoutId = setTimeout(stopToggle, 20000);
      },
    }).mount('#app');
  </script>
</html>
```

When you open the above example on your browser, you'll see a color box appearing and disappearing for a span of 20 seconds.

![Blinking color block](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/lw30g3ssk0u0xfonkky4.gif)

### The v-show directive

We achieve this blinking effect by toggling the state of the **showBox** variable between the true and false states. We can find this in the logic defined in the **mounted** hook. And to bind that state to our box (the div block with the `.box` class) we use the **v-show** Vue.js directive on it.

The ***v-show*** is a custom Vue.js directive that modifies the `display` style of a HTML element based on the [truthiness](https://developer.mozilla.org/en-US/docs/Glossary/Truthy) of the variable passed to it. If it's an expression or value that is [falsy,](https://developer.mozilla.org/en-US/docs/Glossary/Falsy) it adds a `display: none` style to the HTML element in question.

***v-show*** is among Vue.js' conditional directives, i.e. directives that fulfill a task based on the truthiness of the value being observed. Other conditional Vue.js directives include v-if, v-else-if, and v-else. [We will look at these in more depth later](https://vuenoob.com/posts/vuejs-directives-conditional-rendering-in-vue/#the-v-if%2C-v-else-if-and-v-else-directives).

### The v-bind directive

Let's take a look at another example.

```html
<html>
  <style>
    meter {
      height: 3em;
      width: 15em;
    }
  </style>

  <div id="app">
    <h1>Vue City Water Flow Rate Levels</h1>
    <h2>({{'{{'}} level.toFixed() {{'}}'}} m³/hour)</h2>
    <meter
      min="0"
      max="100"
      low="33"
      high="66"
      optimum="80"
      v-bind:value="level"
    ></meter>
    <br />
  </div>
  <script src="https://unpkg.com/vue@3"></script>
  <script>
    let app = Vue.createApp({
      data() {
        return {
          level: 0,
        };
      },
      mounted() {
        const fluctuateLevel = () => {
          this.level = Math.random() * 15 + 60;
        };
        let intervalId = setInterval(fluctuateLevel, 200);
      },
    }).mount('#app');
  </script>
</html>
```

In the above example, we are observing the fluctuating water flow rate in our imaginary city - "Vue City".

![Fluctuating water flow levels](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/49fx2il9lyxhe5tmomjt.gif)

As evident, we are simulating the water levels between values 60 and 75 inside the **fluctuateLevel()** function inside the **mounted** hook.

To succeed in our demonstration, we need to make sure that the **value** attribute of the *meter* element keeps changing by being updated by the value of the **level** Vue.js variable. We achieve this by attaching the *[v-bind](https://vuenoob.com/posts/vuejs-directives-list-and-conditional-rendering/#the-v-bind-directive/)* directive whose function is to bind the values of reactive Vue.js variables to HTML element attributes, in our case the **level** variable to the **value** attribute of the *meter* element (`v-bind:value="level"`). Hence, whenever **level** changes, the element's attribute immediately gets the updated value, in-turn updating the meter we see on the page. 

## Binding HTML with the v-html directive

Not only does Vue.js support binding for plain variables, but it also has a custom directive that handles the binding for HTML markup, the ***v-html***.

This directive can be quite handy when trying to display content such as a blog's article content fetched from an external data API.

Let's demonstrate this in an example.

```html
<html>
  <div id="app">
    <h1>{{'{{'}} title {{'}}'}}</h1>
    <div>
      <h2>With v-html</h2>
      <article v-html="htmlContent"></article>
    </div>
    <div>
      <h2>without v-html</h2>
      <article> {{'{{'}} htmlContent {{'}}'}} </article>
    </div>
  </div>
  <script src="https://unpkg.com/vue@3"></script>
  <script>
    let app = Vue.createApp({
      data() {
        return {
          title: '',
          htmlContent: ''
        }
      },
      async mounted() {
        await fetch('https://hacker-news.firebaseio.com/v0/item/121003.json?print=pretty')
          .then((res) => res.json())
          .then((res) => {
            console.log(res);
            this.htmlContent = res.text;
            this.title = res.title;
          })
      },
    }).mount("#app");
  </script>
</html>
```

In the example above, we are fetching data from the [Hacker news API](https://github.com/HackerNews/API) and extracting a **title** and **text** containing HTML tags.
Trying to render the HTML content inside the **htmlContent** variable inside the mustache syntax as seen in the first section does not give us intended results as the HTML content is plotted as is. This is not what we want to see in such a case.
Binding the same variable onto the second article tag using the ***v-html*** directive gives us what we want, having the HTML inside our variable rendered as part of the existing page template.

The asynchronous **fetch** method above is nothing other than a helper that is assisting us in fetching remote data. You can read more about the *[fetch API here](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API/Using_Fetch)*.

We will cover more tutorials involving fetching data from external data API in the future. This is just a simple example demonstrating the gist of it.

After getting introduced to Vue.js directives, we'll be going in depth on conditional and list rendering inside Vue.js templates while using them in the [next post](https://vuenoob.com/posts/vuejs-directives-conditional-rendering-in-vue/).