Menu Close

List Rendering with Vue.js — Numbers, Components, and Templates

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 rendering a range of numbers, rendering components and templates, and more.

v-for with a Range

v-for can take an integer to render a range of numbers. For example, if we have the following:

src/index.js :

new Vue({  
  el: "#app",  
  data: {}  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="[https://cdn.jsdelivr.net/npm/vue/dist/vue.js](https://cdn.jsdelivr.net/npm/vue/dist/vue.js)"></script>  
  </head><body>  
    <div id="app">  
      <span v-for="num in 10">  
        {{num}}  
      </span>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then we see:

1 2 3 4 5 6 7 8 9 10

v-for on a Template

We can use v-for to loop through template elements. For example, we can write:

src/index.js :

new Vue({  
  el: "#app",  
  data: {}  
});

index.html :

<!DOCTYPE html>  
<html>  
  <head>  
    <title>App</title>  
    <meta charset="UTF-8" />  
    <script src="[https://cdn.jsdelivr.net/npm/vue/dist/vue.js](https://cdn.jsdelivr.net/npm/vue/dist/vue.js)"></script>  
  </head> <body>  
    <div id="app">  
      <template v-for="num in 10">  
        <span>  
          {{num}}  
        </span>  
        <span>|</span>  
      </template>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then we get:

1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |

displayed on the screen.

v-for with v-if

v-for has higher priority than v-if if they’re used together.

However, we shouldn’t use them together because of the higher precedence of v-for over v-if .

If we want to filter some elements out when we render items from an array, we should use a computed property.

If we only render a small fraction of array elements, it has to iterate over the entire list and then check if the expression we set it truthy.

For example, the following JavaScript and HTML code:

src/index.js :

new Vue({  
  el: "#app",  
  data: {  
    numbers: [1, 2, 3, 4, 5]  
  }  
});

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">  
      <span v-for="num in numbers" v-if="num !== 3">  
        {{num}}  
      </span>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

is not very efficient since every time the loop is rendered, Vue has to iterate through every element and then check if num !== 3 is true .

Instead, we should use a computed property as follows:

src/index.js :

new Vue({  
  el: "#app",  
  data: {  
    numbers: [1, 2, 3, 4, 5]  
  },  
  computed: {  
    not3() {  
      return this.numbers.filter(p => p !== 3);  
    }  
  }  
});

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">  
      <span v-for="num in not3">  
        {{num}}  
      </span>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

The code above is more efficient because not3 is only recomputed when numbers change.

Also, only the items in not3 is iterated through during render, so v-for doesn’t have to loop through all the items.

There’s also less logic in the template, which keeps it clean. Maintenance is much easier.

We can also get performance benefits from moving v-if to the parent element that has the v-for , so whatever’s inside is only rendered when the condition is met.

For example, if we have:

src/index.js :

new Vue({  
  el: "#app",  
  data: {  
    persons: ["Joe", "Jane", "Mary"],  
    show: false  
  }  
});

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-if="show">  
        <div v-for="person in persons">  
          {{person}}  
        </div>  
      </div>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then nothing is rendered since show is false . Vue doesn’t have to do the work to look at whatever’s inside.

This is much better than:

<!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-for="person in persons" v-if="show">  
        {{person}}  
      </div>  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

In the code above, Vue has to loop through each entry and check if the condition in the v-if returns a truthy value.

As we can see, even though the code is only slightly different, but the performance implications are big.

v-for with a Component

We can use v-for on custom components just like with any other element.

For example, we can write the following:

src/index.js :

Vue.component("num", {  
  props: ["num"],  
  template: "<span>{{num}}</span>"  
});new Vue({  
  el: "#app",  
  data: {  
    numbers: [1, 2, 3, 4, 5]  
  }  
});

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">  
      <num v-for="num in numbers" :num="num" :key="num" />  
    </div>  
    <script src="src/index.js"></script>  
  </body>  
</html>

Then we get:

12345

displayed on the screen.

Note that we have the :key attribute provided. This is required since Vue 2.2.0.

Also, we passed num into the num component’s num prop by writing:

:num="num"

This lets us inject what we want to the component, reducing coupling between them.

Conclusion

We can render a range of numbers with v-for by providing it with a number instead of an array or an object.

v-for and v-if shoudn’t be used together so that v-if doesn’t have to run in each iteration and we can also reduce the number of items that are iterated through.

Also, we can loop through template and components with v-for like any other element.

Posted in vue