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 how to render lists with thev-for
directive.
Using v-for to Map Array to Elements
We can use the v-for
directive to render a list of items from an array.
For example, we can use it as follows:
src/index.js
:
new Vue({
el: "#app",
data: {
persons: [{ name: "Joe" }, { name: "Jane" }, { name: "Mary" }]
}
});
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-for="person in persons">
{{person.name}}
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
In the code above, we have the v-for
directive, and then we write person in persons
to loop through the data.persons
array.
Then we get the name
property from each entry and display it.
person
is an alias for the array element being iterated on.
Then we get:
Joe
Jane
Mary
All the properties of the array entry is available during iteration.
We can also add an optional second argument to access the index of the array. For example, we can write the following:
src/index.js
:
new Vue({
el: "#app",
data: {
persons: [{ name: "Joe" }, { name: "Jane" }, { name: "Mary" }]
}
});
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-for="(person, index) in persons">
{{index}} - {{person.name}}
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
Then we get:
0 - Joe
1 - Jane
2 - Mary
We can also use of
instead of in
to match the for...of
loop syntax in JavaScript:
<!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 of persons">
{{person.name}}
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
Photo by Jens Kreuter on Unsplash
v-for with an Object
We can also use v-for
to loop through the values of an object.
So if we write the following:
src/index.js
:
new Vue({
el: "#app",
data: {
book: {
title: "JavaScript Book",
author: "John Smith",
publishedYear: 2019
}
}
});
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-for="value in book">
{{value}}
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
And we get:
JavaScript Book
John Smith
2019
We can loop through the keys of the object by providing a second argument to the expression as follows:
src/index.js
:
new Vue({
el: "#app",
data: {
book: {
title: "JavaScript Book",
author: "John Smith",
publishedYear: 2019
}
}
});
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-for="(value, key) in book">
{{key}} - {{value}}
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
Then we get:
title - JavaScript Book
author - John Smith
publishedYear - 2019
Also, we can provide a third argument for the index
of the object entry.
To do this, we can write:
src/index.js:
new Vue({
el: "#app",
data: {
book: {
title: "JavaScript Book",
author: "John Smith",
publishedYear: 2019
}
}
});
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-for="(value, key, index) in book">
{{index}}: {{key}} - {{value}}
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
Then we get:
0: title - JavaScript Book
1: author - John Smith
2: publishedYear - 2019
The order of iteration over an object is based on the enumeration order of Object.keys()
, which isn’t guaranteed to be consistent across JavaScript engine implementations.
Maintaining State
v-for
by default updates the items in place instead of moving the DOM elements to match the order of the items to make sure it reflects what should be rendered at a particular index.
Therefore, it’s only suitable when the list doesn’t rely on child component state or temporary DOM state like input values.
To make sure Vue knows which elements are unique, we should provide a key
attribute via the v-bind:key
directive.
For example, we can write:
src/index.js
:
new Vue({
el: "#app",
data: {
persons: [{ name: "Joe" }, { name: "Jane" }, { name: "Mary" }]
}
});
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-for="person in persons" v-bind:key="person.name">
{{person.name}}
</div>
</div>
<script src="src/index.js"></script>
</body>
</html>
We have to use primitive values as keys.
The key
attribute is a generic mechanism for Vue to identify nodes.
Conclusion
We can use v-for
to iterate through entries of an array or entries of an object and render the entries.
To use it to render arrays, we can either use in
or of
. Also, we can access the index of an array entry with v-for
.
To iterate through objects, we can do the same thing, except that the first argument is the value of a property, the second argument is the key and the third is the index.
Only the first argument is required in each case.
The key
attribute can be set so the Vue can identify unique nodes. We can set it to a primitive value with v-bind:key
.