Welcome to the new vue academy ! It will be a list of lot of article on vue! I have 2.5 years of experience in this and I can teach a few thing about this !
With vue you can use some directives, today we will see v-for
in details !
What is ?
v-for
is a directive use to render a list of items based on an array or an object.
<template>
<div>
<div
v-for="item in toto"
:key="item"
>
{{ item }}
</div>
</div>
</template>
<script>
import Vue from "vue"
export default Vue.extend({
data() {
return {
toto: [ 'first', 'second', 'third' ],
}
},
})
</script>
In this component we will have three div as below π
first
second
third
You can also get the current index of the iterated item
<div
v-for="(item, index) in toto"
:key="item"
>
{{ item }} {{ index }}
</div>
It works also with object ! If we replace toto: [ 'first', 'second', 'third' ]
by an object like toto: { a: 1, b: 2, c: 3 }
We have π
1
2
3
We can also access to the current key !
<div
v-for="(item, attribute) in toto"
:key="item"
>
{{ item }} {{ attribute }}
</div>
The key
attribute
With the example above, you can ask what is this :key
value?
In vue, :key
is used in all components, if the key is changed, the component will be reload (destroy and created hook will be triggered). It a simply way to reload properly a component !
In general you don't need to handle this attribute, but in the v-for
, key
is MANDATORY
!
And why ?
To give Vue a hint so that it can track each nodeβs identity, and thus reuse and reorder existing elements, you need to provide a unique key attribute for each item.
I advise you to never use index
as key attribute, always use a unique ID. The answer is not complicated to illustrate, imagine again an array with 1000 items, you delete the second item, so the length
of the iterated array will be changed, and all index of all items will changed, so all components will be reload !
If you use a unique id by item, and you delete the second item, the other component will be not reload since all of the key is not changed !
v-for with v-if
You should NEVER use v-for
with v-if
, since when they exist on the same node, v-for
has a higher priority than v-if
. That means the v-if
will be run on each iteration of the loop separately !
Let's go through an example !
<template>
<div>
<div
v-for="item in numberList"
v-if="isEven(item)"
:key="item"
>
{{ item }}
</div>
</div>
</template>
<script>
import Vue from "vue"
export default Vue.extend({
data() {
return {
numberList: [ 1, 2, 3, 4, 5, 6 ],
}
},
methods: {
isEven(item) {
return item % 2 === 1
},
},
})
</script>
For each iteration we will execute the isEven
function !
How to avoid this?
Two solutions based on the context:
First
We need to filter some value in your array !
Use computed
property and iterate it !
<template>
<div>
<div
v-for="evenItem in evenList"
:key="evenItem"
>
{{ evenItem }}
</div>
</div>
</template>
<script>
import Vue from "vue"
export default Vue.extend({
data() {
return {
numberList: [ 1, 2, 3, 4, 5, 6 ],
}
},
computed: {
evenList() {
return this.numberList.filter(item => this.isEven(item))
}
},
methods: {
isEven(item) {
return item % 2 === 0
},
},
})
</script>
Here we filter the array before iterate it ! We don't need to use v-if
!
Second
I need to display the items only if the array size is equal to 5 for exemple.
You can just add an other balise that will wrap the v-for
, it will contain the v-if
!
<template>
<div>
<div v-if="numberList.length === 5" >
<div
v-for="item in numberList"
:key="item"
>
{{ item }}
</div>
</div>
</div>
</template>
Conclusion
v-for
is used to show array or object keys, you need to always use a unique id as key
attribute.
Never use v-for
with v-if
, depending on the current context you have other possibilities !
I hope you like this reading!
π You can get my new book Underrated skills in javascript, make the difference
for FREE if you follow me on Twitter and MP me π
Or get it HERE
π MY NEWSLETTER
βοΈ You can SUPPORT MY WORKS π
πββοΈ You can follow me on π
π Twitter : https://twitter.com/code__oz
π¨βπ» Github: https://github.com/Code-Oz
And you can mark π this article!
Top comments (4)
Small tip. You can use
template
withv-if/else
to avoid unwanted elements in the DOM.Instead of
do this
Nice tips James! Totally agree!
Hi! I don't get it. Why did you still declare "isEven" method if you just filtered the array in the "computed" declaration?
Tanks in advance.
Hey bro I miss it I just replace it by
this.numberList.filter(item => this.isEven(item))
! Thank you you rock!