DEV Community

Ryan John
Ryan John

Posted on • Originally published at vureact.top

Vue v-for to React: How does VuReact compile it?

VuReact is a compiler toolchain for migrating from Vue to React — and for writing React with Vue 3 syntax. In this article, we dive straight into the core: how Vue's common v-for directive is compiled into React code by VuReact.

Before We Start

To keep the examples easy to read, this article follows two simple conventions:

  1. All Vue and React snippets focus on core logic only, with full component wrappers and unrelated configuration omitted.
  2. The discussion assumes you are already familiar with Vue 3's v-for directive usage.

Compilation Mapping

Basic array iteration

The simplest v-for directive, used to iterate over an array and render list items.

  • Vue
<li v-for="(item, i) in list" :key="item.id">{{ i }} - {{ item.name }}</li>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
{
  list.map((item, i) => (
    <li key={item.id}>
      {i} - {item.name}
    </li>
  ));
}
Enter fullscreen mode Exit fullscreen mode

As the example shows, Vue's v-for directive is compiled into React's map function. VuReact adopts an array mapping compilation strategy, converting template directives into JSX array expressions. This fully preserves Vue's list rendering semantics — iterating over each element in the array, generating corresponding JSX elements, and automatically handling the key attribute to ensure React's rendering performance.


Object iteration

v-for can also be used to iterate over object properties and values.

  • Vue
<li v-for="(val, key, i) in obj" :key="key">{{ i }} - {{ key }}: {{ val }}</li>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
{
  Object.entries(obj).map(([key, val], i) => (
    <li key={key}>
      {i} - {key}: {val}
    </li>
  ));
}
Enter fullscreen mode Exit fullscreen mode

For object iteration, VuReact adopts an Object.entries conversion strategy, converting Vue's object iteration syntax into Object.entries(obj).map() form. This compilation approach fully simulates Vue's object iteration semantics — iterating over key-value pairs in order, preserving the (value, key, index) parameter order, and ensuring consistent data rendering.


Nested v-for loops

Complex nested list rendering using multiple layers of v-for.

  • Vue
<div v-for="category in categories" :key="category.id">
  <h3>{{ category.name }}</h3>
  <ul>
    <li v-for="product in category.products" :key="product.id">
      {{ product.name }} - ${{ product.price }}
    </li>
  </ul>
</div>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
{
  categories.map((category) => (
    <div key={category.id}>
      <h3>{category.name}</h3>
      <ul>
        {category.products.map((product) => (
          <li key={product.id}>
            {product.name} - ${product.price}
          </li>
        ))}
      </ul>
    </div>
  ));
}
Enter fullscreen mode Exit fullscreen mode

For nested loops, VuReact adopts a nested map function compilation strategy, converting Vue's nested v-for into nested map function calls. This compilation approach fully preserves Vue's nested loop semantics — each iteration of the outer loop creates a complete inner loop list, maintaining the hierarchical relationship of the component structure.


v-if + v-for

Real-world business logic often requires combining conditions with list rendering.

  • Vue
<template v-if="cond" v-for="user in users" :key="user.id">
  <img :src="user.avatar" :alt="user.name" />
  <div class="user-info">
    <h4>{{ user.name }}</h4>
    <p>{{ user.email }}</p>
    <span class="role-badge">{{ user.role }}</span>
  </div>
  <div class="user-actions">
    <button @click="editUser(user.id)">Edit</button>
    <button @click="deleteUser(user.id)" class="danger">Delete</button>
  </div>
</template>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
{
  cond
    ? users.map((user) => (
        <div key={user.id} className="user-card">
          <img src={user.avatar} alt={user.name} />
          <div className="user-info">
            <h4>{user.name}</h4>
            <p>{user.email}</p>
            <span className="role-badge">{user.role}</span>
          </div>
          <div className="user-actions">
            <button onClick={() => editUser(user.id)}>Edit</button>
            <button onClick={() => deleteUser(user.id)} className="danger">
              Delete
            </button>
          </div>
        </div>
      ))
    : null;
}
Enter fullscreen mode Exit fullscreen mode

For conditional list rendering, VuReact demonstrates intelligent conditional compilation:

  1. Condition-first compilation: Converts v-if into a ternary expression wrapping the entire v-for rendering result
  2. Automatic key extraction: When a :key attribute exists on a <template> tag, it is automatically passed to the first child element inside it

VuReact's compilation strategy fully preserves Vue's list rendering semantics while generating code that follows React best practices.


v-for with range values

Vue's v-for also supports iterating over a numeric range.

  • Vue
<span v-for="n in 5" :key="n">{{ n }}</span>
Enter fullscreen mode Exit fullscreen mode
  • Compiled React
{
  Array.from({ length: 5 }, (_, n) => (
    <span key={n + 1}>{n + 1}</span>
  ));
}
Enter fullscreen mode Exit fullscreen mode

For range value iteration, VuReact adopts an Array.from conversion strategy, converting Vue's numeric range syntax into array generation and mapping. This compilation approach fully simulates Vue's range iteration semantics — starting from 1 up to and including the specified number, preserving iteration order and value consistency.

Related Links

Top comments (0)