Vue Academy #4: v-for directive
Tags: vue, javascript, webdev, typescript
Published: 2021-08-06 14:27:43

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.

```vue
<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

```html
    <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 !

```html
    <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 !

```vue
<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 !

```vue
<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` !

```vue
<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](https://twitter.com/code__oz) and MP me 😁

Or get it [HERE](https://codeoz.gumroad.com/l/RXLYp)

🎁 [MY NEWSLETTER](https://www.getrevue.co/profile/code__oz)

☕️ You can [SUPPORT MY WORKS](https://www.buymeacoffee.com/CodeoZ) 🙏

🏃‍♂️ You can follow me on 👇

🕊 Twitter : [https://twitter.com/code__oz](https://twitter.com/code__oz)

👨‍💻 Github: https://github.com/Code-Oz

And you can mark 🔖 this article!