你的 Vue 3 defineEmits(),VuReact 会编译成什么样的 React?

VuReact 是一个能将 Vue 3 代码编译为标准、可维护 React 代码的工具。今天就带大家直击核心:Vue 中常见的 defineEmits 宏经过 VuReact 编译后会变成什么样的 React 代码?

前置约定

为避免示例代码冗余导致理解偏差,先明确两个小约定:

  1. 文中 Vue / React 代码均为核心逻辑简写,省略完整组件包裹、无关配置等内容;
  2. 默认读者已熟悉 Vue 3 中 defineEmits 的 API 用法与核心行为。

编译对照

Vue defineEmits → React props 事件回调映射

defineEmits 是 Vue 3 <script setup> 中用于声明组件自定义事件的宏,它会把事件名称和参数类型定义为函数签名。VuReact 会将它编译为 React props 的事件回调形式,并对事件名做驼峰映射。

  • Vue 代码:
html 复制代码
<script setup lang="ts">
  defineProps<{ name?: string }>();

  const emit = defineEmits<{
    (e: 'save-item', payload: { id: string }): void;
    (e: 'update:name', value: string): void;
  }>();

  const submit = () => {
    emit('save-item', { id: '1' });
    emit('update:name', 'next');
  };
</script>
  • VuReact 编译后 React 代码:
tsx 复制代码
type ICompProps = {
  name?: string;
  onSaveItem?: (payload: { id: string }) => void;
  onUpdateName?: (value: string) => void;
};

const submit = useCallback(() => {
  props.onSaveItem?.({ id: '1' });
  props.onUpdateName?.('next');
}, [props.onSaveItem, props.onUpdateName]);

从示例可以看到:Vue 的 defineEmits 不会直接编译为运行时 Hook,而是转换为 React 组件 props 中的回调函数。VuReact 会将事件名 save-item / update:name 映射为 onSaveItem / onUpdateName,并保留参数类型定义,实现了事件签名与 React props 回调的无缝对接。


Vue v-model:xxx → React 双向绑定 props + 事件映射

此外,子组件中定义的 update:xxx 这类事件,通常用于实现 Vue 中父子组件的双向数据绑定 ,父组件会以 v-model:xxx="value" 的形式使用。VuReact 充分考虑了这种模式,能够精准地进行转换:

  • 父组件 Vue 代码:
html 复制代码
<template>
  <Child v-model:name="current" />
</template>

<script setup>
  // @vr-name: Parent
  const current = ref('');
</script>
  • VuReact 编译后 React 代码:
tsx 复制代码
const Parent = memo(() => {
  const current = useVRef('');
  return <Child name={current.value} onUpdateName={value => current.value = value} />
});

Vue emit 调用 → React props 回调调用

在 Vue 中,emit('event-name', payload) 触发组件自定义事件;在 React 中,VuReact 会把它编译为 props.onEventName?.(payload) 的调用形式。

  • Vue 代码:
html 复制代码
<script setup lang="ts">
  const emit = defineEmits<{
    (e: 'submit', value: string): void;
  }>();

  const handleSubmit = () => {
    emit('submit', 'ok');
  };
</script>
  • VuReact 编译后 React 代码:
tsx 复制代码
type ICompProps = {
  onSubmit?: (value: string) => void;
};

const handleSubmit = useCallback(() => {
  props.onSubmit?.('ok');
}, [props.onSubmit]);

VuReact 会对 emit 的事件名和参数进行类型映射,并在必要时自动为 useCallback 生成依赖数组,让 React 端的回调引用保持稳定,同时避免开发者手动维护依赖。


Vue defineEmits 兼容事件名映射规则

VuReact 支持将 Vue 的短横线事件名、冒号事件名等映射为 React 的驼峰命名回调:

  • save-item → onSaveItem
  • update:name → onUpdateName
  • close → onClose

这种映射方式与 React 事件 props 习惯一致,也保持了 Vue 事件声明的语义。

🔗 相关资源


✨ 如果你觉得本文对你理解 VuReact 有帮助,欢迎点赞、收藏、关注!

相关推荐
A黄俊辉A5 天前
uniapp webview中实现 app和内嵌的H5双向通信
vue.js·json
晨米酱5 天前
AGENTS.md:Agent 的上下文策略层
面试·架构·agent
卡布鲁5 天前
把一个 Vite + Vue3 应用塞进 qiankun (React + Umi3) 主站:十个坑的复盘
前端·javascript·react.js
honkun65 天前
vue 表格组件 vxe-table 配置 ajax 请求自动加载数据与表单查询
vue.js·vxe-table
彧azz5 天前
Linux 环境下 Redis 学习总结:数据类型、持久化、锁、事务、主从与缓存问题
linux·redis·笔记·学习·面试
kybs19915 天前
全球灾害数据分析可视化 毕业设计-附源码66794
vue.js·spring boot·mysql·安全·django·c#·asp.net
雪芽蓝域zzs5 天前
第26章:ECharts 自定义主题 + 页面一键切换主题(深色 / 浅色两套)
vue.js·echars
雪芽蓝域zzs5 天前
第22章:ECharts 图表联动(多图表交互联动)
vue.js·echars
daols885 天前
vue 表格组件 vxe-table 实现虚拟滚动与无需滚动加载
vue.js·vxe-table
雪芽蓝域zzs5 天前
第18章:ECharts 折线图 + 标记点、标记线,自定义 tooltip
vue.js·echars