VuReact 是一个能将 Vue 3 代码编译为标准、可维护 React 代码的工具。今天我们不讲某个 API 的映射,而是从宏观层面看:Vue 的 <script setup> 如何被编译成一个完整的 React 组件。
前置约定
为避免示例冗长,本文聚焦于 <script setup> 的整体编译结果和结构变化:
<script setup>本身是一个编译宏,不会在运行时保留;- 其内部顶层代码会被提炼为 React 组件函数体;
- Vue 模板最终会被转成 JSX 的
return语句。
编译对照
JavaScript:<script setup> 到 React 组件函数
- Vue 代码:
html
<script setup>
const props = defineProps({
title: String,
count: Number,
});
const emit = defineEmits(['update']);
const handleClick = () => {
emit('update', props.count + 1);
};
</script>
<template>
<button @click="handleClick">
{{ props.title }} - {{ props.count }}
</button>
</template>
- VuReact 编译后 React 代码:
jsx
const Comp = memo((props) => {
const handleClick = useCallback(() => {
props.onUpdate?.(props.count + 1);
}, [props.onUpdate, props.count]);
return (
<button onClick={handleClick}>
{props.title} - {props.count}
</button>
);
});
export default Comp;
这段转换显示了 <script setup> 的核心编译思路:
- 非纯 UI 组件会被
memo包裹以进行性能优化。 defineProps不是运行时调用,而是被编译为组件的props参数;defineEmits被编译为props.onXxx的事件回调;- 你在
script setup中编写的大多数代码,直接成为组件内部的函数; - 对 script 代码进行编译时静态优化;
- Vue 模板被编译为
return (...)中的 JSX。
TypeScript:带类型的 <script setup> 整体编译
- Vue 代码:
html
<script setup lang="ts">
const props = defineProps<{
title: string;
count: number;
}>();
const emit = defineEmits<{
(e: 'update', value: number): void;
}>();
const handleClick = () => {
emit('update', props.count + 1);
};
</script>
<template>
<button @click="handleClick">
{{ props.title }} - {{ props.count }}
</button>
</template>
- VuReact 编译后 React 代码:
tsx
type ICompProps = {
title: string;
count: number;
onUpdate?: (value: number) => void;
};
const Comp = memo((props: ICompProps) => {
const handleClick = useCallback(() => {
props.onUpdate?.(props.count + 1);
}, [props.onUpdate, props.count]);
return (
<button onClick={handleClick}>
{props.title} - {props.count}
</button>
);
});
这说明:
<script setup lang="ts">中的类型信息会被保留并转换为组件props类型;defineProps的类型参数最终用在 Reactprops类型定义上;defineEmits的事件类型会映射成onUpdate的回调类型。
在 TypeScript 环境下,VuReact 也支持将 defineProps 和 defineEmits 的 JavaScript 运行时参数写法,编译为对应的 TS 类型信息。
- Vue 代码:
ts
const props = defineProps({
title: String,
count: Number,
});
const emit = defineEmits(['update']);
- VuReact 编译后 React 代码:
tsx
type ICompProps = {
title: string;
count: number;
onUpdate?: () => any;
};
相关资源
- VuReact 官方文档:vureact.top
- VuReact Runtime 文档:runtime.vureact.top
如果你觉得本文对你理解 VuReact 有帮助,欢迎点赞、收藏、关注!