We deal with lists day in and day out. In our applications, we often face situations where we have to display arrays as lists whose items change dynamically. So, hardcoding array items in our HTML is not really an option. It is important that we know how to handle these dynamically changing arrays with Vue and not so surprisingly, we have another directive for just that! Tada, it’s v-for! As always, we will dive deep with loads of examples for clear understanding.
Iterating through an array
The most frequent and simplest scenario we face is to loop over the items of an array and render them as a list. Below is an array of greetings in four different languages which we would like to display as an unordered list to our webpage.
data: {
greetings: ["hi", "bonjour", "hola", "ciao"]
}
In our index.html
file, let us add the v-for
directive to the <li>
element to dynamically render the contents of greetings array like so,
<ul>
<li v-for="greeting in greetings">{{ greeting }}</li>
</ul>
Okay, don’t panic! I will dissect this information word by word.
The special syntax that we have for the v-for
directive here is, “greeting in greetings
”.
- Firstly, greeting – it is recommended to use a singular noun, greeting in our case, as an alias for the array element being iterated on. This can be any name of your choice which can then be used in our code to address each array item.
- Secondly, in – delimiter that comes as part of the syntax. If you have JavaScript background, then all this should seem pretty familiar because there we use
for in
andfor of
for iteration purpose. Even with Vue, we can useof
as the delimiter instead ofin
for the ease of it.
<li v-for="greeting of greetings">{{ greeting }}</li>
- Finally, greetings – this has to be the exact same name of the array as in the Vue instance’s
data
object.
Here, for simplicity, we are using the variable greeting
in simple interpolation. But it can be used just like any other property like, passing it as a value to a function or binding it to the reference of a link etc. The output is as follows,
An alternative to using mustache syntax is to use the v-text
directive. It sets greeting
as the text content.
<ul>
<li v-for="greeting in greetings" v-text=greeting></li>
</ul>
The same result will be rendered.
Vue is reactive!
Let’s take a trip down the memory lane. We learned that the beauty of Vue lies in its reactivity.
Quick recap: Keeping the state and view in sync. In other words, Vue not only renders the data in the DOM where it is being referenced but also updates it whenever its value is changed in the data object.
Let us see this in action, one more time.
Open Chrome DevTools with the shortcut F12 and click on ‘Vue’. This panel will only be present if you have followed along with our tutorial series and installed Vue Devtools Chrome extension.
Since we have not used any global variables to refer to the Vue instance in our index.js
file, it will be saved to $vm0
by default. This can be seen once you click on the <Root>
as shown in the below image. So, let’s use $vm0
to access the Vue model from the Developer Tools Console.
Let’s go to the console and use the push
method to add one more greeting to our greetings
array and see if the view is updated reactively (magically!).
$vm0.greetings.push("namaste")
Isn’t this magical?!
Accessing the index of the current array item
A developer’s life has no pause button! We are expected to accomplish unexpected things such as accessing the index of the array item along with its content. We know how to render the array elements with Vue but is it possible to get its index too? Well, the answer turns out to be YES!
The syntax is pretty similar to what we saw earlier,
<div v-for="(greeting, index) in greetings">{{ index }}. {{ greeting}}</div>
We have to introduce a parenthesis and specify two arguments separated by a comma, whose names can be of our choice. The first argument refers to the array element – greeting
in our case. The second argument is optional and it refers to the index of the current item being looped – index
in our example. This order is the most important thing to remember here. Whatever names you give, the first is always the array element and the second is the index in the v-for syntax. It can then be used with those names in the code as required.
Let us take a look at the final 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>
</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"]
}
});
All the code discussed above is also available in the GitHub repo. Feel free to fork the repository and run some experiments.
We will be looking at how to iterate over objects with v-for in our next post. Until then, keep practicing!