VuReact 是一个能将 Vue 3 代码编译为标准、可维护 React 代码的工具。今天就带大家直击核心:Vue 中常见的 v-for 指令经过 VuReact 编译后会变成什么样的 React 代码?
前置约定
为避免示例代码冗余导致理解偏差,先明确两个小约定:
- 文中 Vue / React 代码均为核心逻辑简写,省略完整组件包裹、无关配置等内容;
- 默认读者已熟悉 Vue 3 中的 v-for 指令用法。
编译对照
基础数组遍历
最简单的 v-for 指令,用于遍历数组并渲染列表项。
- Vue 代码:
<li v-for="(item, i) in list" :key="item.id">{{ i }} - {{ item.name }}</li>
- VuReact 编译后 React 代码:
{
list.map((item, i) => (
<li key={item.id}>
{i} - {item.name}
</li>
));
}
从示例可以看到:Vue 的 v-for 指令被编译为 React 的 map 函数。VuReact 采用 数组映射编译策略,将模板指令转换为 JSX 数组表达式,完全保持 Vue 的列表渲染语义——遍历数组中的每个元素,生成对应的 JSX 元素,并自动处理 key 属性以保证 React 的渲染性能。
对象遍历
v-for 也可以用于遍历对象的属性和值。
- Vue 代码:
<li v-for="(val, key, i) in obj" :key="key">{{ i }} - {{ key }}: {{ val }}</li>
- VuReact 编译后 React 代码:
{
Object.entries(obj).map(([key, val], i) => (
<li key={key}>
{i} - {key}: {val}
</li>
));
}
对于对象遍历,VuReact 采用 Object.entries 转换策略,将 Vue 的对象遍历语法转换为 Object.entries(obj).map() 形式。这种编译方式完全模拟 Vue 的对象遍历语义——按顺序遍历对象的键值对,保持 (值, 键, 索引) 的参数顺序,确保数据渲染的一致性。
嵌套 v-for 循环
复杂的嵌套列表渲染,使用多层 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>
- VuReact 编译后 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>
));
}
对于嵌套循环,VuReact 采用 嵌套 map 函数编译策略,将 Vue 的嵌套 v-for 转换为嵌套的 map 函数调用。这种编译方式完全保持 Vue 的嵌套循环语义——外层循环的每个迭代都会创建内层循环的完整列表,保持组件结构的层次关系。
v-if + v-for
实际业务中经常需要结合条件进行列表渲染。
- 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)">编辑</button>
<button @click="deleteUser(user.id)" class="danger">删除</button>
</div>
</template>
- VuReact 编译后 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)}>编辑</button>
<button onClick={() => deleteUser(user.id)} className="danger">
删除
</button>
</div>
</div>
))
: null;
}
对于带条件的列表渲染,VuReact 展示了智能的条件编译能力:
- 优先条件编译:将
v-if转换为三元表达式,包裹整个v-for渲染结果 - 自动提取 key:当
<template>标签上存在:key属性时,会自动将其传递给内部的第一个子元素 - 事件绑定处理:
@click转换为onClick,并自动包装为箭头函数以传递参数 - 属性绑定转换:
:src、:alt等转换为 React 属性语法 - 样式类名处理:
class转换为className,符合 React 规范
VuReact 的编译策略完全保持 Vue 的列表渲染语义,同时生成符合 React 最佳实践的代码。
使用 v-for 范围值
Vue 的 v-for 也支持使用数字范围进行迭代。
- Vue 代码:
<span v-for="n in 5" :key="n">{{ n }}</span>
- VuReact 编译后 React 代码:
{
Array.from({ length: 5 }, (_, n) => (
<span key={n + 1}>{n + 1}</span>
));
}
对于范围值迭代,VuReact 采用 Array.from 转换策略,将 Vue 的数字范围语法转换为数组生成和映射。这种编译方式完全模拟 Vue 的范围迭代语义——从 1 开始到指定数字结束(包含),保持迭代顺序和数值的一致性。
🔗 相关资源
- VuReact 官方文档:语义编译对照总览
✨ 如果你觉得本文对你理解 VuReact 有帮助,欢迎点赞、收藏、关注!