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.