10. Rendering Lists Part 2 (Iterating over objects)

Hope you are already aware of iterating over array elements using v-for directive. In our applications, we deal with objects as much as arrays. So, without further ado let’s understand how to iterate over the various properties of an object. I hear you say, “what about an array of objects then?” I got you. We will handle that scenario too!

Iterating over objects

Time to add a simple object to our Vue instance’s data object.

var app = new Vue({
  el: "#app",
  data: {
    greetings: ["hi", "bonjour", "hola", "ciao"],
    letters: {
      a: "apple",
      b: "banana",
      c: "cat"
    }
  }
});

In order to loop over the key-value pairs of an object, we can use the same v-for directive.

1. Accessing the values of an object

It is very simple to access the values of an object.

<div v-for="value in letters"> {{ value }} </div>

Isn’t this syntax very similar to iterating over array values? If we just want to get the value from each key-value pair, then this would suffice.

  • value’ – This can be any name of your choice. Use the same name to access each value.
  • letters’ – This has to be the same object name as in the data object.

Accessing object values

2. Accessing the key and value

If we want to have more than one argument in the v-for syntax, then we have to use a parenthesis. The order is important here.

  • The first argument will always be the value and
  • The second argument will be the key.

The argument names can be anything of our choice. Let us use value and key as argument names for simplicity and easy understanding.

<div v-for="(value, key) in letters">
  {{ key }} for {{ value }}
</div>

Object key-value pairs

3. Accessing key, value and current index

A third argument can be used to get the current index of the key-value pair being accessed. Once again, the order of these arguments is important. The first argument will always be the value, the second will be the key and the third, current index. The argument names can be of our choice as always. Don’t forget to enclose all these arguments in parenthesis. For better understanding, let us use ‘k’ for the key, ‘v’ for value and ‘i’ for the current index.

<div v-for="(v, k, i) in letters">
  {{ k }} for {{ v }} - ({{ i }})
</div>

Sticky note: It is important to note that the order in which these key-value pairs are displayed, may vary over different browsers. Because the order is based on the results of Object.keys() which returns all the keys of an object.

Since the argument names can be anything of our liking, the below code also gives the same results.

<div v-for="(value, key, index) in letters">
  {{ key }} for {{ value }} - ({{ index }})
</div>

Iterating over an array of objects

Let’s say we have an array of two simple objects in our data object.

movies: [
      { character: "Iron man", name: "Avengers" },
      { character: "groot", name: "Guardians of the Galaxy" }
    ]

In order to access the values of each object in the array,

<li v-for="movie in movies">
  <strong>Movie name:</strong> {{ movie.name }} and <br/>
  <strong>Character:</strong> {{ movie.character }}
</li>
  • movie in movies – gets each object from the movies array in the ‘movie’ variable
  • movie.nameand movie.character – gets the values of the keys, name and character respectively, from the individual object currently being looped and saved in the ‘movie’ variable.

Remember, in case you don’t want to use the dot operator or render the key-value pairs dynamically then you can nest another v-for directive. Of course, you can nest any number of v-for directives within.

So, the alternative code for using dot operators is,

<li v-for="movie in movies">
  <div v-for="(value, key) in movie">
    {{ key }}: {{ value }}
  </div>
</li>

array of objects

Keeping track with unique ‘key’ attribute

While working with simple lists, we can use the v-for directive just the way we discussed so far. But you might come across some unexpected behavior while dealing with child components (which we will see later in this tutorial series), updating the list elements etc. To avoid such bumps while coding, it is always recommended to provide a unique value and bind it to a special key attribute as shown below,

<li v-for="movie in movies" v-bind:key="movie.name">

Hoping that the name of the movie is unique. This will help Vue to track each node’s identity.

Iterating over a range

If you come across a situation where you just want to print numbers starting from 1 to some fixed integer, then once again, it’s just a cakewalk with Vue’s v-for directive.

For example,

<span v-for="num in 3">
  • num – any variable name of your choice which will represent the current number while looping over the given range
  • in – delimiter (as per the syntax)
  • 3 – range which signifies the last number that will be considered while looping.

Suppose, we want to print numbers from 1 to 3, five times. It is pretty easy following the above example,

<div v-for="number in 5">
  <strong>{{ number }}. </strong>
  <span v-for="num in 3"> {{ num }} </span> 
  &nbsp;
</div>

The outer v-for keeps track of the number of times the code within the <div> tags is repeated and the inner v-for generates a range of integers from 1 to 3.

Printing numbers

Instead of taking a peek at individual snippets, let us just see the complete code.

index.html

<!DOCTYPE html>
<html>
  <head>
    <title>Hello Vue!</title>
    <!-- including Vue with development version CDN -->
    <script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
  </head>
  <body>
    <div id="app">
      <h2>Greetings</h2>
      <!-- Iterating through array elements -->
      <ul>
        <li v-for="greeting in greetings" v-text=greeting></li>
      </ul>
      <!-- Accessing array elements along with thier index -->
      <h2>Greetings with Index</h2>
      <div v-for="(greeting, index) in greetings">
          {{ index }}. {{ greeting}}
      </div>
      <hr/>
      <!-- Iterating through objects -->
      <h2>Object values</h2>
      <div v-for="value in letters">{{ value }}</div>
      <hr/>
      <h2>Object key-value pairs</h2>
      <div v-for="(value, key) in letters">
        {{ key }} for {{ value }}
      </div>
      <hr/>
      <h2>Object key-value and index</h2>
      <div v-for="(value, key, index) in letters">
        {{ key }} for {{ value }} - ({{ index }})
      </div>
      <hr/>
      <!-- Iterating over an array of objects -->
      <ul>
        <li v-for="movie in movies" v-bind:key="movie.name">
          <strong>Movie name:</strong> {{ movie.name }} and <br/>
          <strong>Character:</strong> {{ movie.character }}
        </li>
      </ul>
      <!-- Alternative method -->
      <h4> Aliter </h4>
      <ul>
        <li v-for="movie in movies">
          <div v-for="(value, key) in movie">
            {{ key }}: {{ value }}
          </div>
        </li>
      </ul>
      <hr/>
      <!-- Iterating over numbers -->
      <div v-for="number in 5">
        <strong> {{ number }}. </strong>
        <span v-for="num in 3"> {{ num }} </span> 
        &nbsp;
      </div>
    </div>
    <!-- including index.js file -->
    <script src="index.js"></script>
  </body>
</html>

index.js

var app = new Vue({
  el: "#app",
  data: {
    greetings: ["hi", "bonjour", "hola", "ciao"],
    letters: {
      a: "apple",
      b: "banana",
      c: "cat"
    },
    movies: [
      { character: "Iron man", name: "Avengers" },
      { character: "groot", name: "Guardians of the Galaxy" }
    ]
  }
});

All the code discussed above is also available in the GitHub repo.

Moral of the story, v-for – one directive to rule them all! ?

Have a nice day ahead.

Leave A Comment

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.