DEV Community

Cover image for Display your list: v-for 🫨
Domenico Tenace
Domenico Tenace

Posted on • Updated on • Originally published at domenicotenace.dev

Display your list: v-for 🫨

Overview

Vue allows object list rendering to be simple and clean: v-for directive.
In this article we will explain how this is possible and when to use this feature.
Let's start! 🤙


How v-for works?🤔

The v-for directive render a list of items based on an array: requires a special syntax in the form of item in items, where items is the source data array and item is an alias for the array element being iterated.
In the following lines, there is a basic example of v-for use:

<script setup>
import { ref } from "vue"

const wizards = ref([{name:'Tom', surname:'Riddle'}, {name:'Harry', surname:'Potter'}]);
</script>

<template>
   <ul>
     <li v-for="wizard in wizards">Complete name: {{ wizard.name }} {{ wizard.surname }}</li>
   </ul>
</template>

Enter fullscreen mode Exit fullscreen mode

v-for support second param during iteration: the index.
Consider the previous example: let's add the index.

<script setup>
import { ref } from "vue"

const wizards = ref([{name:'Tom', surname:'Riddle'}, {name:'Harry', surname:'Potter'}]);
</script>

<template>
   <ul>
     <li v-for="(wizard, index) in wizards">
      {{ index }} Complete name: {{ wizard.name }} {{ wizard.surname }}
     </li>
   </ul>
</template>

Enter fullscreen mode Exit fullscreen mode

In this way will display the index of everything element of the array.
For nested v-for, scoping also works similar to nested functions.
Each v-for scope has access to parent scopes:

 <li v-for="item in items">
    <span v-for="childItem in item.children">
      {{ item.message }} {{ childItem }}
    </span>
  </li>
Enter fullscreen mode Exit fullscreen mode

v-for with object

You can also use v-for to iterate through the properties of an object. The iteration order will be based on the result of calling Object.keys() on the object:

<script setup>
import { reactive } from "vue"

const wizard = reactive({name:'Harry', surname:'Potter', role:'Wizard'});
</script>

<template>
   <ul>
     <li v-for="(value, key, index) in wizards">
       {{ index }}. {{ key }}: {{ value }}
     </li>
   </ul>
</template>

Enter fullscreen mode Exit fullscreen mode

The above example is the complete way to render the values of object: key and index are the key of the object and the index of iteration, meanwhile value is the value of the key.
Obviously it is possible to render only the value.

v-for with a Range

v-for can also take an integer. In this case it will repeat the template that many times, based on a range.

 <li v-for="item in 10">{{ item }}</li>
Enter fullscreen mode Exit fullscreen mode

In this case, will display ten number from 1 to 10.

v-for on template

Similar to template v-if, Vue allows use v-for on <template> for render multiple code's blocks.

<ul>
  <template v-for="wizard in wizards">
    <li>{{ wizard.name }} - {{ wizard.surname }}</li>
    <li class="divider"></li>
  </template>
</ul>
Enter fullscreen mode Exit fullscreen mode

v-for with v-if

It's not recommended to use v-if and v-for on the same element due to implicit precedence.

Follow this scenario:v-if and v-for on the same node. What is the problem?
v-if has a higher priority than v-for, that means the v-if condition will not have access to variables from the scope of the v-for.

<!--
This will throw an error because property "todo"
is not defined on instance.
-->
<li v-for="todo in todos" v-if="!todo.isComplete">
  {{ todo.name }}
</li>
Enter fullscreen mode Exit fullscreen mode

It's possible solve this by moving v-for into a <template> wrapper:

<template v-for="todo in todos">
  <li v-if="!todo.isComplete">
    {{ todo.name }}
  </li>
</template>
Enter fullscreen mode Exit fullscreen mode

Key for the state

Vue by default uses an "in-place patch" strategy, updating a list of rendered items with v-for. If the order of the data elements has changed, instead of moving the DOM elements to match the element order, Vue will patch each element in place and make sure it reflects what should be displayed in that particular index.

To give Vue a hint so that it can track the identity of each node and then reuse and reorder existing elements, you need to provide a unique key attribute for each element.
In this case the key attribute comes into play:

<div v-for="wizard in wizards" :key="wizard.id">
     {{ wizard }}
</div>
Enter fullscreen mode Exit fullscreen mode

The key is a special attribute that must be a primitive value.
The key feature is unique and it is recommended to provide it with v-for whenever possible.
Third-party libraries such as Lodash provide functions to generate unique keys.

Conclusion

The v-for directive in Vue.js is a powerful and flexible tool for rendering lists of data in your applications. Its simplicity and versatility make it an essential feature for Vue developers, allowing them to iterate through arrays and objects effortlessly, while also providing the freedom to customize the rendering process as needed.
Happy coding!✨


Hi👋🏻
My name is Domenico, software developer passionate of Vue.js framework, I write article about it for share my knowledge and experience.
Don't forget to visit my Linktree to discover my projects 🫰🏻

Linktree: https://linktr.ee/domenicotenace

Follow me on dev.to for other articles 👇🏻

Top comments (1)

Collapse
 
zede profile image
Denis

And thats still not all power of v-for can be used with ALL iterbale objects: Map / Set / generators. And can even iterates by a string