VueJs Directives: Data Binding in VueJs

Last updated on April 1, 2022. Created on March 30, 2022.


Important

To get the maximum learning value out of this post, make sure you engage in practical programming by running the code blocks provided to see them in action. Click here to learn how to do that.

Introduction

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, this is made possible by directly binding the target HTML tag inner content, attributes and events to the Vue instance with the help of various custom Vue directives.

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

Custom Vue Directives

To see Vue directives in action, let’s observe the following example:

Practice this code!
<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/[email protected]"></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 coral box appearing and disappearing for a span of 20 seconds.

We achieve that by toggling the state of the showBox variable between true and false, as found 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 directive on it.

The v-show is a custom Vue directive that modifies the display style of a HTML element based on the truthiness of the variable passed to it. If it’s an expression or value that is falsy, it adds a display: none style to the HTML element in question.

v-show is among Vue’s conditional directives, i.e. directives that fulfill a task based on the truthiness of the value being observed, the others being v-if, v-else-if, and v-else. We will look at these in more depth later.

Let’s take a look at another example.

Practice this code!
<html>
  <style>
    meter {
      height: 3em;
      width: 15em;
    }
  
</style>

  <div id="app">
    <h1>City Water Flow Rate Levels</h1>
    <h2>({{ level.toFixed() }} m³/hour)</h2>
    <meter
      id="fuel"
      min="0"
      max="100"
      low="33"
      high="66"
      optimum="80"
      v-bind:value="level"
    >
</meter>
    <br />
  </div>
  <script src="https://unpkg.com/[email protected]"></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 of our imaginary city - “Vueland”.

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 variable. We achieve this by attaching the v-bind directive whose function is to bind reactive values to HTML element attributes to the targeted attribute in our case 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, changing the meter we see on the page.

Binding HTML

Not only does Vue support binding of plain variables, but also has a custom directive that handles the binding of HTML tags straight into other HTML elements, 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.

Practice this code!
<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/[email protected]"></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 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 with 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.

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 VueJs directives, we’ll be going in length on conditional and list rendering on the Vue templates while using them in the next post.

Next

VueJs Directives: Conditional Rendering in Vue

Previous

Vue.js Computed Properties in Depth

Subscribe to the VueNoob Newsletter

[[[ noty.message ]]]

By using this site, you agree that you have read and understand its Privacy Policy.