VuReact 是一款Vue 转 React 编译工具它能将 Vue 3 代码编译为标准、可维护的纯 React 。 Githubgithub.com/vureact-js/core 官方文档https://vureact.top 写在前面本教程帮助开发者在最短时间内上手 VuReact并完成一个入门 Vue 3 项目到 React 项目的编译转换并启动应用。你将掌握从环境搭建、组件编写、编译配置到产物验证的全流程无需深入了解 React 语法细节即可利用现有 Vue 技能生成可运行的 React 工程。完成后你会明确以下四件事输入 SFC 在什么约定下可稳定转换编译后目录会长什么样输出 TSX 与原始 SFC 的语义对应关系编译器自动分析并追加 React hook 依赖无需手动管理 推荐先观看下方的 2 分钟演示视频快速建立对整个流程的直观印象。VuReact 快速入门演示开始新建 Vite Vue 工程使用Vite新建一个标准的Vue 3TS项目npx create-vitelatest vue-app--templatevue-ts当出现交互式选择Install with npm and start now?时选择No。你将会看到类似以下工程目录结构示意vue-app/ ├─ public/ ├─ src/ │ ├─ assets/ │ ├─ components/ │ │ └─ HelloWorld.vue │ ├─ App.vue │ ├─ main.ts │ └─ style.css ├─ index.html ├─ package.json ├─ tsconfig.json ├─ vite.config.ts └─ ...第1步安装 VuReact进入目录并安装项目依赖cdvue-appnpminstall安装 VuReact 编译核心npminstall-Dvureact/compiler-core第2步配置 VuReact在vue-app目录下新建vureact.config.ts// vue-app/vureact.config.tsimport{defineConfig}fromvureact/compiler-core;exportdefaultdefineConfig({// 输入路径包含要编译的 Vue 文件允许输入单文件 xxx.vueinput:./src,// 排除 Vue 入口文件避免语义冲突exclude:[src/main.ts],output:{// 工作区目录存放编译产物和缓存workspace:.vureact,// 输出目录名outDir:react-app,// 自动初始化 Vite React 环境bootstrapVite:true,},});除exclude需手动指定外其余选项均使用默认值无需额外配置。第3步编写 Vue 组件3.1 实现一个简单的计数器将原来的HelloWorld.vue替换为计数器组件代码!-- src/components/HelloWorld.vue --templatesectionclasscounter-cardh1{{ props.title }}/h1h2spanclassvureactVuReact/span➕spanclassvueVue/spanspanclassreactReact/span({{ count }})/h2p{{ title }}/pbuttonclickincrement1/buttonbuttonclickmethods.decrease-1/button/section/templatescriptsetuplangts// vr-name: HelloWorldimport{computed,ref,watch}fromvue;// 除了顶部的特殊注释外也可以使用宏定义组件名// defineOptions({ name: HelloWorld });// 必须使用 defineProps 定义 propsconstpropsdefineProps{title?:string}();// 必须使用 defineEmits 定义 emitsconstemitsdefineEmits{(e:update,value:number):void;}();conststepref(1);constcountref(0);consttitlecomputed(()阶数x${step.value});constincrement(){count.valuestep.value;emits(update,count.value);};constmethods{decrease(){count.value-step.value;emits(update,count.value);},};watch(count,(newVal){step.valueMath.floor(newVal/10)||1;});/script!-- VuReact 支持处理 Less 和 Sass --stylescoped.counter-card{border:1px solid #ddd;border-radius:8px;padding:12px;.vureact{color:#9932cc;}.vue{color:#42b883;}.react{color:#61dafb;}}/style3.2 修改App.vue!-- src/App.vue --scriptsetuplangts// vr-name: AppimportHelloWorldfrom./components/HelloWorld.vue;/scripttemplateHelloWorldtitle计数器组件update(v) {console.log(v)}//template第4步编译到 React 工程方式一使用 npx 命令在vue-app目录下运行# 全量/增量编译npx vureact build# 或监听模式npx vureactwatch方式二使用 npm scripts在package.json里添加脚本命令scripts:{vr:build:vureact build,vr:watch:vureact watch}npmrun vr:build运行命令后终端会输出相关编译信息。第5步查看输出目录树输出到vue-app/.vureact工作区目录示意vue-app/ ├── .vureact/ # 工作区编译生成 │ ├── cache/ # 编译缓存 │ ├── react-app/ # 生成的 Vite React 工程 │ │ ├── src/ │ │ │ ├── components/ │ │ │ │ ├── HelloWorld.tsx │ │ │ │ └── HelloWorld-[hash].css │ │ │ ├── App.tsx │ │ │ ├── index.css │ │ │ ├── main.tsx │ │ │ └── style.css │ │ └── package.json │ │ └── tsconfig.json │ │ └── vite.config.ts │ │ └── ... │ │ ├── src/ # 原始 Vue 代码 ├── ... └── vureact.config.js # VuReact 配置文件第6步运行 React 应用进入react-app目录cd.vureact/react-app安装依赖npmruninstall启动项目npmrun dev进入页面后你可能会发现与 Vue 的页面样式存在差异这是因为 Vite 初始化 React 后自带的默认样式index.css注入到了main.tsx中导致的手动调整即可。如遇问题可查阅 常见问题 章节。第7步对照生成结果下面是一个格式化后的典型输出为说明做了轻微简化实际哈希与属性名以本地产物为准import{useComputed,useVRef,useWatch}fromvureact/runtime-core;import{memo,useCallback,useMemo}fromreact;import./HelloWorld-ebf8d8dc.css;// VuReact 根据 defineProps 和 defineEmits 自动生成exporttypeIHelloWorldProps{title?:string;}{onUpdate?:(value:number)void;};// 自动使用 memo 优化组件constHelloWorldmemo((props:IHelloWorldProps){// ref/computed 转换成了对等的适配 APIconststepuseVRef(1);constcountuseVRef(0);consttitleuseComputed(()阶数x${step.value});// 自动分析顶层箭头函数依赖并追加 useCallback 优化constincrementuseCallback((){count.valuestep.value;props.onUpdate?.(count.value);// emits 转换},[count.value,step.value,props.onUpdate]);// 自动分析顶层变量中的依赖并追加 useMemo 优化constmethodsuseMemo(()({decrease(){count.value-step.value;props.onUpdate?.(count.value);},}),[count.value,step.value,props.onUpdate],);// watch 转成对等适配 APIuseWatch(count,(newVal){step.valueMath.floor(newVal/10)||1;});return(section classNamecounter-carddata-css-ebf8d8dch1 data-css-ebf8d8dc{props.title}/h1h2 data-css-ebf8d8dcspanclassvureactdata-css-ebf8d8dcVuReact/span➕spanclassvuedata-css-ebf8d8dcVue/spanspanclassreactdata-css-ebf8d8dcReact/span({count.value})/h2{/* 自动补齐 ref .value 访问 */}p data-css-ebf8d8dc{title.value}/pbutton onClick{increment}data-css-ebf8d8dc1/buttonbutton onClick{methods.decrease}data-css-ebf8d8dc-1/button/section/);});// 自动保持组件导出exportdefaultCounter;CSS 文件内容.counter-card[data-css-ebf8d8dc]{border:1px solid #ddd;border-radius:8px;padding:12px;background:#fafafa;.vureact[data-css-ebf8d8dc]{color:#9932cc;}.vue[data-css-ebf8d8dc]{color:#42b883;}.react[data-css-ebf8d8dc]{color:#61dafb;}}关键观察点// vr-name: Counter这段特殊注释定义了组件名defineProps和defineEmits被转换成了 TS 组件类型非纯 UI 展示组件默认会走memo包装ref/computed/watch被转换为 runtime 适配 APIuseVRef/useComputed/useWatch模板事件回调会生成符合 React 语义的onClick顶层箭头函数自动分析依赖尝试注入useCallback顶层变量声明自动分析依赖尝试注入useMemo对 JSX 中的原ref/computed状态值补上.valuescoped样式会生成带哈希的 css 文件并在元素上标注作用域属性总结通过以上步骤你已完成了一个 Vue SFC 项目到 React 项目的完整编译流程。回顾整个过程初始化项目使用 Vite 创建标准的 Vue TS 工程安装编译器添加vureact/compiler-core依赖编写配置通过vureact.config.ts指定输入、排除和输出规则编写组件按照约定vr-name注释、defineProps/defineEmits宏编写 SFC执行编译使用 CLI 命令一键转换运行产物直接启动生成的 React 工程并验证效果VuReact 在编译过程中拥有以下核心转换能力Vue 模板语法 → React JSXv-if/v-slot/v-model/slot等Composition API → React Hooksref→useVRef、computed→useComputed响应式依赖分析 → 自动注入useCallback/useMemo依赖数组组件通信 → Props 类型推导 事件回调映射样式处理 → Scoped CSS / CSS Modules / 预处理器一站式编译常见问题对于使用过程中的常见问题可参考以下文档ESLint 规则冲突FAQ 推荐阅读为什么运行时套壳注定失败Vue 转 React 应走编译时路线29号更新Vue3转React实战VuReact 可控混写迁移实战Vue转React终极指南VuReact全特性语义对照✨ 如果你觉得本文对你理解 VuReact 有帮助欢迎点赞、收藏、关注Github 仓库点亮 Star ⭐