VuReact 是一个能将 Vue 3 代码编译为标准、可维护 React 代码的工具。今天就带大家直击核心:Vue 中常见的defineEmits宏经过 VuReact 编译后会变成什么样的 React 代码?
前置约定
为避免示例代码冗余导致理解偏差,先明确两个小约定:
- 文中 Vue / React 代码均为核心逻辑简写,省略完整组件包裹、无关配置等内容;
- 默认读者已熟悉 Vue 3 中
defineEmits的 API 用法与核心行为。
编译对照
Vue defineEmits → React props 事件回调映射
defineEmits是 Vue 3<script setup>中用于声明组件自定义事件的宏,它会把事件名称和参数类型定义为函数签名。VuReact 会将它编译为 Reactprops的事件回调形式,并对事件名做驼峰映射。
- Vue 代码:
<scriptsetuplang="ts">defineProps<{name?:string}>();constemit=defineEmits<{(e:'save-item',payload:{id:string}):void;(e:'update:name',value:string):void;}>();constsubmit=()=>{emit('save-item',{id:'1'});emit('update:name','next');};</script>- VuReact 编译后 React 代码:
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 代码:
<template><Childv-model:name="current"/></template><scriptsetup>// @vr-name: Parentconstcurrent=ref('');</script>- VuReact 编译后 React 代码:
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 代码:
<scriptsetuplang="ts">constemit=defineEmits<{(e:'submit',value:string):void;}>();consthandleSubmit=()=>{emit('submit','ok');};</script>- VuReact 编译后 React 代码:
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→onSaveItemupdate:name→onUpdateNameclose→onClose
这种映射方式与 React 事件 props 习惯一致,也保持了 Vue 事件声明的语义。
🔗 相关资源
- VuReact 官方文档:https://vureact.top
- VuReact Runtime 文档:https://runtime.vureact.top
📖 继续阅读
- 上一篇:defineProps
- 下一篇:defineSlots
✨ 如果你觉得本文对你理解 VuReact 有帮助,欢迎点赞、收藏、关注!