大家好,我是前端开发者。最近在做Vue3 项目迁移 React,发现最繁琐、最容易出错的就是Props 类型转换。
手动把 defineProps 改成 React 接口太费时间,还容易丢类型、漏参数。于是我基于 VuReact 做了一套Vue 转 React 自动工具,今天把核心的 defineProps 全自动转换 分享给大家,真正做到Vue 转 React 不用改代码,直接跑在 React18 上。
前言
Vue3 <script setup> 里的 defineProps 太香了,但迁移到 React 时就很痛苦:
- 要手写
interface Props - 要把
defineEmits改成onXxx回调 - 复杂类型、泛型、嵌套结构要重新整理
- 多人协作容易改出类型bug
Vue React 迁移成本高,大多就高在这些重复体力活上。
今天这篇文章,带你用 VuReact 实现: ✅ Vue3 defineProps 自动转 React Props ✅ defineEmits 自动转 onXxx 回调 ✅ 泛型 / 联合类型 / 导入类型 完美保留 ✅ 直接生成可上线的 React18 代码 ✅ 支持 Vue React 混合开发
一、先看效果:Vue → React 一键搞定
Vue 原代码(defineProps + defineEmits)
<script setup lang="ts">
defineProps<{
userId: number;
userName: string;
}>()
defineEmits<{
update: [id: number, name: string]
delete: [id: number]
cancel: []
}>()
</script>
<template>
<div>
<p>{{ userName }}</p>
<button @click="$emit('update', userId, '新名字')">更新</button>
<button @click="$emit('delete', userId)">删除</button>
</div>
</template>
自动转换成 React 代码(零修改)
interface Props {
userId: number;
userName: string;
onUpdate?: (id: number, name: string) => void;
onDelete?: (id: number) => void;
onCancel?: () => void;
}
const UserCard: React.FC<Props> = ({
userId, userName, onUpdate, onDelete
}) => {
const handleUpdate = () => {
onUpdate?.(userId, '新名字')
}
const handleDelete = () => {
onDelete?.(userId)
}
return (
<div>
<p>{userName}</p>
<button onClick={handleUpdate}>更新</button>
<button onClick={handleDelete}>删除</button>
</div>
)
}
// Vue转React by VuReact
体验:复制 → 编译 → 直接用,这就是Vue 转 React 最佳实践。
二、defineProps 在 Vue3 中的标准写法
先回顾一下我们日常最常用的几种 defineProps 风格,后面都会被自动转换。
1. 基础类型
<script setup lang="ts">
defineProps<{
title: string
count: number
isActive?: boolean
}>()
</script>
2. 复杂嵌套 + 数组 + 回调
<script setup lang="ts">
defineProps<{
user: {
id: number
name: string
email: string
}
items: Array<{
id: string
label: string
value: any
}>
onSelect?: (id: string) => void
}>()
</script>
这些在 VuReact 里全部一键识别、自动转换。
三、核心转换规则(前端人一看就懂)
1. 类型映射表(直接收藏)
| Vue 写法 | React 写法 | 说明 |
|---|---|---|
| string | string | 直接保留 |
| number | number | 直接保留 |
| boolean | boolean | 直接保留 |
| T[] | T[] | 数组不变 |
| (e) => void | onXxx?: (e)=>void | 事件自动转驼峰 |
| Record<K,V> | Record<K,V> | 高级类型保留 |
| [number,number] | [number,number] | 元组保留 |
| a?: T | a?: T | 可选属性完全一致 |
2. 可选属性自动处理
// Vue
defineProps<{
required: string
optional?: number
}>()
// React
interface Props {
required: string
optional?: number
}
四、实战场景全覆盖
场景 1:基础属性 + 联合类型
<script setup lang="ts">
defineProps<{
name: string
age: number
isAdmin?: boolean
tags: string[]
status: 'pending' | 'active' | 'completed'
}>()
</script>
转换后
interface Props {
name: string
age: number
isAdmin?: boolean
tags: string[]
status: 'pending' | 'active' | 'completed'
}
const UserProfile: React.FC<Props> = ({
name, age, isAdmin = false, status
}) => {
return (
<div>
<h1>{name}</h1>
<p>年龄: {age}</p>
<p>状态: {status}</p>
</div>
)
}
// Vue转React by VuReact
场景 2:泛型组件(高级常用)
Vue3 泛型组件 <script setup generic="T"> 也完美支持:
<script setup lang="ts" generic="T extends { id: string }">
defineProps<{
items: T[]
getItemLabel: (item: T) => string
onItemSelect: (item: T) => void
}>()
</script>
React 自动生成泛型组件
interface GenericProps<T extends { id: string }> {
items: T[]
getItemLabel: (item: T) => string
onItemSelect: (item: T) => void
}
function GenericList<T extends { id: string }>({
items, getItemLabel, onItemSelect
}: GenericProps<T>) {
return (
<ul>
{items.map(item => (
<li key={item.id} onClick={() => onItemSelect(item)}>
{getItemLabel(item)}
</li>
))}
</ul>
)
}
// Vue转React by VuReact
场景 3:外部类型导入(企业项目必备)
<script setup lang="ts">
import { User, Product } from '@/types'
defineProps<{
currentUser: User
featuredProduct: Product
}>()
</script>
转换后自动保留 import
import { User, Product } from '@/types'
interface Props {
currentUser: User
featuredProduct: Product
}
const Dashboard: React.FC<Props> = ({
currentUser, featuredProduct
}) => {
return <div>仪表板</div>
}
// Vue转React by VuReact
五、3 分钟上手使用
1. 安装
npm install -D @vureact/compiler-core
2. 写一个 Vue 组件
<script setup lang="ts">
defineProps<{
title: string
count: number
active?: boolean
}>()
</script>
<template>
<div>
<h1>{{ title }}</h1>
<p>计数: {{ count }}</p>
</div>
</template>
3. 一键编译
npx vureact build
4. 直接拿到 React 组件
interface Props {
title: string
count: number
active?: boolean
}
const Example: React.FC<Props> = ({
title, count, active = false
}) => {
return (
<div>
<h1>{title}</h1>
<p>计数: {count}</p>
</div>
)
}
// Vue转React by VuReact
六、这套工具能解决什么真实问题?
1. 企业项目大规模迁移
- 几百个组件不用手动改 Props
- 类型安全 100% 保留
- 大幅降低Vue React 迁移成本
2. 组件库跨端输出
- Vue 组件库 → 自动生成 React 版本
- API 保持一致,减少维护成本
3. 混合开发架构
- 老项目 Vue,新项目 React
- 组件互通、类型互通、无痛过渡
七、工具优势(为什么比手写/其他工具强)
✅ 全自动:defineProps / defineEmits 一键转换
✅ 类型不丢:泛型、联合类型、嵌套、导入全保留
✅ 生产可用:代码风格符合 React 规范
✅ 零侵入:不破坏原有 Vue 项目
✅ 极速:批量编译,秒级输出
八、总结
如果你正在做:
- Vue3 项目迁移 React18
- Vue 组件转 React 组件
- 想降低 Vue React 迁移成本
- 需要 Vue React 混合开发
那这套 defineProps 自动转换 绝对是刚需级工具,真正做到: Vue 写组件,React 直接用,一行代码不用改。
📕 推荐阅读
🔗 相关资源
- GitHub:github.com/vureact-js/…
- Gitee:gitee.com/vureact-js/…
- 官方文档:vureact.top
- 在线演示:codesandbox.io/p/github/vu…