How to Loop X Times in a Range Using the Vue v-for Directive

To loop x times in a range using Vue's v-for directive, pass a numeric value directly to the expression—such as v-for="n in 10"—which renders the block that many times while supplying a 1-based index to the template.

When working with the vuejs/vue repository, understanding how to loop x times in a range using the Vue v-for directive helps you render static or dynamic lists without maintaining dummy array data. This pattern is powered by internal runtime helpers that detect numeric sources and generate iterations efficiently.

How the v-for Directive Handles Numeric Ranges

Vue’s template compiler delegates list rendering to the renderList helper located in src/core/instance/render-helpers/render-list.ts. When the v-for source expression evaluates to a number, renderList treats it as a range, creates an array of that length, and invokes the render callback for each iteration.

The callback receives two arguments: (i + 1, i), meaning the first parameter is the 1-based index (what your template sees as the loop variable) and the second is the 0-based index used internally.

During compilation, the directive’s expression is parsed by parseFor in src/compiler/parser/index.ts. This function extracts the alias (e.g., n) and the source expression (e.g., 10). If the source is a numeric literal or a variable holding a number, it flows unchanged into renderList, triggering the range behavior.

Syntax for Looping X Times in Vue.js

The syntax for looping x times in a range using the Vue v-for directive follows the standard alias in source pattern, where the source is a number:

v-for="n in count"
  • n receives the current iteration value (1, 2, 3, ...).
  • count can be a numeric literal (e.g., 5) or a reactive data property.

You can also use the of keyword interchangeably:

v-for="n of 10"

Practical Examples

Static Numeric Range

To render a fixed number of items, provide an integer literal directly:

<ul>
  <li v-for="n in 5" :key="n">
    Item number {{ n }}
  </li>
</ul>

This renders five list items displaying "Item number 1" through "Item number 5".

Dynamic Range from Data

When the iteration count depends on component state, bind to a data property:

<template>
  <div>
    <button @click="count++">Add Row</button>
    <button @click="count = Math.max(0, count - 1)">Remove Row</button>

    <p v-for="i in count" :key="i">
      Dynamic row {{ i }} of {{ count }}
    </p>
  </div>
</template>

<script>
export default {
  data() {
    return {
      count: 3
    }
  }
}
</script>

Initially, this renders three paragraphs. Clicking the buttons updates the range reactively.

Using the Index in Templates

Although the loop variable provides the 1-based value, you can access the underlying 0-based index by using the second argument in the v-for expression:

<div v-for="(n, index) in 5" :key="n">
  <span>Human-readable: {{ n }}</span>
  <span>Zero-based index: {{ index }}</span>
</div>

Here, n ranges from 1 to 5, while index ranges from 0 to 4.

Key Implementation Details

Understanding the internals of how to loop x times in a range using the Vue v-for directive helps optimize rendering performance and debug edge cases.

1-based indexing for ranges: When renderList detects a number, it generates values starting at 1, not 0. This differs from array iteration where the first argument is the item itself.

Source files to know:

Performance characteristics: Numeric ranges are converted to arrays internally, so v-for="n in 1000" creates a 1000-item array during render. For extremely large static ranges, consider computed properties or virtual scrolling to avoid unnecessary memory allocation.

Summary

  • Loop x times in a range using the Vue v-for directive by passing a numeric value: v-for="n in 10".
  • The loop variable receives a 1-based index (1 through X) when iterating over numbers.
  • Internally, the renderList helper in src/core/instance/render-helpers/render-list.ts converts the number to an array and manages the iteration.
  • Always bind a :key to each item for efficient DOM updates, especially with dynamic numeric ranges.

Frequently Asked Questions

Can I use v-for with a variable number of iterations?

Yes. The source expression in v-for can be a reactive data property or computed value. When the number changes, Vue re-renders the list automatically. For example, v-for="n in count" where count is defined in data() will update the DOM whenever count is modified.

Does Vue's v-for use 0-based or 1-based indexing for numeric ranges?

Vue uses 1-based indexing for numeric ranges. When you write v-for="n in 5", the variable n will be 1, 2, 3, 4, and 5 on successive iterations. However, if you access the second argument—v-for="(n, index) in 5"—that index is 0-based (0 through 4), consistent with JavaScript array conventions.

How do I access the current index when looping x times?

Use the destructuring syntax with two parameters: v-for="(item, index) in count". Here, item receives the 1-based value (1, 2, 3...), while index receives the 0-based position (0, 1, 2...). This pattern is processed by the parseFor function in src/compiler/parser/index.ts and rendered via renderList.

Is there a performance difference between v-for on arrays vs numeric ranges?

There is minimal runtime performance difference because Vue’s renderList helper normalizes numeric ranges into temporary arrays before iteration. However, extremely large numeric ranges (e.g., v-for="n in 100000") can cause memory overhead during the render phase. For large datasets, prefer computed properties that slice the range or implement virtual scrolling rather than rendering thousands of DOM nodes directly.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →