Skip to content

Vue Loop Statements

In Vue, we use the v-for directive to perform loop rendering. It can render a list based on an array, or be used to iterate over an object or a numeric range.

v-for Iterating Over Arrays

The v-for directive requires a special syntax in the form item in items, where items is the source data array and item is the alias for the array element being iterated.

vue
<script setup>
import { ref } from 'vue'

const items = ref([
  { id: 1, message: 'Foo' },
  { id: 2, message: 'Bar' }
])
</script>

<template>
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.message }}
    </li>
  </ul>
</template>

v-for also supports an optional second parameter, which is the index of the current item.

vue
<template>
  <ul>
    <li v-for="(item, index) in items" :key="item.id">
      {{ index }} - {{ item.message }}
    </li>
  </ul>
</template>

Importance of :key

The v-for directive requires us to provide a key attribute. key is a special attribute that Vue uses to track the identity of each node, allowing it to reuse and reorder existing elements. The value of key must be a unique string or number.

It is strongly recommended to always provide key in v-for, unless the iterated DOM content is very simple, or you intentionally rely on default behavior for performance gains.

v-for Iterating Over Objects

You can also use v-for to iterate over an object's properties.

vue
<script setup>
import { reactive } from 'vue'

const myObject = reactive({
  title: 'How to do lists in Vue',
  author: 'Jane Doe',
  publishedAt: '2016-04-10'
})
</script>

<template>
  <ul>
    <li v-for="(value, key, index) in myObject" :key="key">
      {{ index }}. {{ key }}: {{ value }}
    </li>
  </ul>
</template>

When iterating over objects, it follows the result of Object.keys(), but consistency across all JavaScript engines is not guaranteed. v-for supports optional second (key) and third (index) parameters.

v-for Iterating Over a Numeric Range

v-for can also accept an integer. In this case, it will repeat the template that many times.

vue
<template>
  <span v-for="n in 10" :key="n">{{ n }} </span>
</template>

The output will be: 1 2 3 4 5 6 7 8 9 10

Using v-for on <template>

Similar to v-if, you can also use a <template> tag with v-for to render a block containing multiple elements. For example:

vue
<ul>
  <template v-for="item in items" :key="item.id">
    <li>{{ item.message }}</li>
    <li class="divider" role="presentation"></li>
  </template>
</ul>

v-for with v-if

When they exist on the same node, v-if has higher priority than v-for. This means the condition of v-if cannot access variables defined within the v-for scope.

This can be solved by moving v-if to a <template> tag that wraps v-for:

vue
<template v-if="shouldRenderItems">
  <ul>
    <li v-for="item in items" :key="item.id">
      {{ item.message }}
    </li>
  </ul>
</template>

If you only want to render some items, you can first filter the list in a computed property, then use the filtered list directly in v-for.

Content is for learning and research only.