30 Days of Vue

Lifecycle Hooks

 

This post is part of the series 30 Days of Vue.

In this series, we're starting from the very basics and walk through everything you need to know to get started with Vue. If you've ever wanted to learn Vue, this is the place to start!

Lifecycle Hooks

Today, we're going to talk a bit about how an instance lives in an application. That is, we'll talk about the Vue instance’s lifecycle.

In a Vue instance, Vue gives us some hooks where we can insert our own functionality at different times in the instance’s lifecycle. In order to hook into the lifecycle, we'll need to define functions on an instance which Vue calls at the appropriate time for each hook. An example of such a lifecycle hook is the created() hook.

created

The created() hook is run when an instance has just been created, where the instance data and events are active, and when the instance can be accessed. Since the created() hook is run the moment an instance has been created but before the DOM has been mounted/rendered, it’s often the ideal moment to fetch data that is needed to populate the instance.

For today's article, let's attempt to display a card element in which its content is to be obtained from an external source. This card would look something like this:

The external data source that is to provide us with the data we need would be the /users resource of JSONPlaceholder - a fake online REST API for testing and prototyping.

As we set our up our Vue instance, we’ll need to initialize all the data we intend to have displayed in the template:

new Vue({
  el: '#app',
  data: {
    name: '',
    email: '',
    company: {
      name: '',
      catchPhrase: '',
    }
  },
});

We’ll utilize the Card UI element from Bulma and bind the data on to our template:

<html>
  <head>
    <link rel="stylesheet" href="./styles.css" />
    <link rel="stylesheet"
      href="https://unpkg.com/[email protected]/css/bulma.css" />
  </head>

  <body>
    <div id="app">
      <div class="card">
        <header class="card-header">
          <p class="card-header-title">
            {{name}}
          </p>
        </header>
        <div class="card-content">
          <div class="content">
            <p>{{company.name}}</p>
            <p>"{{company.catchPhrase}}"</p>
          </div>
        </div>
        <footer class="card-footer">
          <a href="#" class="card-footer-item">
            {{email}}
          </a>
        </footer>
      </div>
    </div>
    <script src="https://unpkg.com/vue"></script>
    <script 
      src="https://unpkg.com/axios/dist/axios.min.js">
    </script>
    <script src="./main.js"></script>
  </body>
</html>

We've introduced a <script> tag that references the axios library which will be the HTTP library we'll use to make our GET request.

At this moment, our card won’t display anything and look like the following:

The floating quotations are the quotations we’re using in the template to wrap {{company.catchPhrase}}
The floating quotations are the quotations we’re using in the template to wrap {{company.catchPhrase}}

Let’s update our Vue instance to make a request to the JSONPlaceholder API. We’ll declare the created() hook and use the axios library to make our request.

new Vue({
  el: '#app',
  data: {
    name: '',
    email: '',
    company: {
      name: '',
      catchPhrase: '',
    }
  },
  created() {
    axios.get(
      'https://jsonplaceholder.typicode.com/users'
    ).then((response) => {
        // Use response to update data
    });
  },
});

The /users resource of the api returns details of 10 different users. For our application, we’ll randomly grab a single user object from the list and update the details of our instance data from that object. This would have our created() hook look something like this:

new Vue({
  el: '#app',
  data: {
    // ...
  },
  created() {
    axios.get(
      'https://jsonplaceholder.typicode.com/users'
    ).then((response) => {
        const data = response.data;
        const randomUser = response.data[
          Math.floor(Math.random() * data.length)
        ];
 
        this.name = randomUser.name;
        this.email = randomUser.email;
        this.company.name = randomUser.company.name;
        this.company.catchPhrase = 
          randomUser.company.catchPhrase;
      });
  },
});

When we launch our app, the created() hook would run even before the DOM is mounted on the template. The axios call that gets fired in the hook happens asynchronously. With potentially poorer connections, the DOM might already be mounted while the async call is still in-flight. This could have the user see the card in its blank slate temporarily.

To make a quick change to alert the user that data might still be in the process of being fetched, we can initialize our instance data properties with 'Loading…' values instead of a blank string:

new Vue({
  el: '#app',
  data: {
    name: 'Loading...',
    email: 'Loading...',
    company: {
      name: 'Loading...',
      catchPhrase: 'Loading...',
    }
  },
  created() {
    // ...
  },
});

The user would now recognize that the app is “loading” if the data hasn’t yet been made available.

At the final state, the app will render the card element with information about a certain user.

Live version - https://30dofv-created.surge.sh

We should also always have an appropriate error case in our request to notify the user that something’s wrong when our call ever fails. We won’t be doing that here, but it might be a good exercise for you to try!

mounted

The mounted() hook is run after the instance has been mounted and where the rendered DOM can be accessed.

What does mounting mean?

Vue tracks and makes changes to a virtual representation of nodes in the DOM tree before patching those changes on to the actual DOM. This in-memory view that Vue maintains and manages for us is often known as the Virtual DOM.

Vue uses the virtual DOM to maintain/manage and track the changes in an application in a “less-expensive” way than directly tracking the changes being made on the actual DOM.

When we talk about mounting, we're talking about the process of converting the virtual elements into actual DOM elements that are placed in the DOM by Vue.

The entire source code for this tutorial series can be found in the GitHub repo, which includes all the styles and code samples.

If at any point you feel stuck, have further questions, feel free to reach out to us by:

Get started now

Join us on our 30-day journey in Vue. Join thousands of other professional Vue developers and learn one of the most powerful web application development frameworks available today.

No spam ever. Easy to unsubscribe.