Vue 转 React 神器!defineProps 全自动转换,一行代码不用改

0 阅读4分钟

大家好,我是前端开发者。最近在做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 写法说明
stringstring直接保留
numbernumber直接保留
booleanboolean直接保留
T[]T[]数组不变
(e) => voidonXxx?: (e)=>void事件自动转驼峰
Record<K,V>Record<K,V>高级类型保留
[number,number][number,number]元组保留
a?: Ta?: 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 直接用,一行代码不用改

📕 推荐阅读

🔗 相关资源