文章目录
- 前言
-
- [🧩 一、概念对比:Vue Fragment vs React Fragment](#🧩 一、概念对比:Vue Fragment vs React Fragment)
- [📦 二、使用示例对比](#📦 二、使用示例对比)
-
- [✅ Vue 3 中使用 Fragment](#✅ Vue 3 中使用 Fragment)
- [✅ React 中使用 Fragment](#✅ React 中使用 Fragment)
- [🔍 三、差异解析](#🔍 三、差异解析)
-
- [1. **使用方式**](#1. 使用方式)
- [2. **传递属性(如 key)**](#2. 传递属性(如 key))
- [3. **插槽系统**](#3. 插槽系统)
- [✅ 总结:选择建议](#✅ 总结:选择建议)
- [🎯 小结](#🎯 小结)
- 底层行为与性能表现
-
- [🧪 一、Fragment 的真实 DOM 行为](#🧪 一、Fragment 的真实 DOM 行为)
-
- [✅ 示例对比](#✅ 示例对比)
-
- [Vue DOM 结构(组件模板内)](#Vue DOM 结构(组件模板内))
- [React DOM 结构](#React DOM 结构)
- [⚙️ 二、编译 & 渲染机制底层差异](#⚙️ 二、编译 & 渲染机制底层差异)
-
- [✅ 示例:VNode 对象结构](#✅ 示例:VNode 对象结构)
-
- [Vue Fragment vnode 示例](#Vue Fragment vnode 示例)
- [React Fragment vnode 示例](#React Fragment vnode 示例)
- [🚀 三、性能对比(渲染效率)](#🚀 三、性能对比(渲染效率))
-
- [✅ 相同点](#✅ 相同点)
- [🔍 不同点](#🔍 不同点)
- [实测结论(单个 Fragment 中渲染 1 万行元素)](#实测结论(单个 Fragment 中渲染 1 万行元素))
- [🧭 四、实际应用建议(跨框架组件)](#🧭 四、实际应用建议(跨框架组件))
- [✅ 总结](#✅ 总结)
前言
Vue 3 的 Fragment 与 React 的 Fragment 在设计理念上非常相似,但在实现和使用方式上存在一些差异。
🧩 一、概念对比:Vue Fragment vs React Fragment
特性 | Vue 3 Fragment | React Fragment |
---|---|---|
支持多根节点 | ✅ 是 | ✅ 是 |
渲染为真实 DOM | ❌ 否(虚拟容器) | ❌ 否 |
使用方式 | 默认启用,无需引入额外组件 | 需要显式使用 <React.Fragment> 或 <> |
插槽支持 | ✅ 插槽内容可返回多个根节点 | ❌ 插槽非内建机制,需要 props.children |
实现机制 | 编译时自动转为 Fragment 虚拟节点 |
JSX 语法 sugar,转为 React.Fragment |
额外属性传递 | ❌ 不支持属性 | ✅ React.Fragment key 可用于列表 |
📦 二、使用示例对比
✅ Vue 3 中使用 Fragment
vue
<!-- 无需引入 Fragment,自动启用 -->
<template>
<h1>Hello</h1>
<p>World</p>
</template>
Vue 编译器自动将其转换为:
ts
return createVNode(Fragment, null, [
h('h1', 'Hello'),
h('p', 'World')
])
✅ React 中使用 Fragment
js
import React from 'react'
function App() {
return (
<>
<h1>Hello</h1>
<p>World</p>
</>
)
}
JSX 编译后会变成:
js
React.createElement(React.Fragment, null,
React.createElement('h1', null, 'Hello'),
React.createElement('p', null, 'World')
)
🔍 三、差异解析
1. 使用方式
- Vue:Fragment 是内建的,无需导入;天然支持
- React :需要写
React.Fragment
或<>
明确表达
2. 传递属性(如 key)
-
React Fragment 可写
key
,常用于.map()
渲染列表jsitems.map(item => ( <React.Fragment key={item.id}> <div>{item.name}</div> <div>{item.value}</div> </React.Fragment> ))
-
Vue Fragment 是编译时产物,不支持
:key
绑定在 Fragment 上(需要用<template>
+v-for
来处理)
3. 插槽系统
- Vue 拥有完整的插槽(slots)系统,可让父组件传递多个根节点给子组件。
- React 使用
props.children
,但无法像 Vue 插槽一样传具名、作用域插槽。
✅ 总结:选择建议
使用情境 | Vue Fragment | React Fragment |
---|---|---|
多根节点输出 | ✅ 推荐 | ✅ 推荐 |
插槽内容多节点 | ✅ 更强插槽能力 | ❌ 插槽不支持 |
列表渲染 key | ❌ 不支持 | ✅ 可使用 key |
编写体验 | ✅ 自动优化 | ✅ JSX 精简语法 |
🎯 小结
- Vue Fragment:自动启用 、插槽友好,专为模板系统设计。
- React Fragment:显式使用,更偏向 JavaScript 逻辑与手动控制。
底层行为与性能表现
深入对比 Vue Fragment vs React Fragment 的底层行为与性能表现,尤其在真实渲染 DOM、组件嵌套复杂度、渲染效率等方面,为你在构建大型或跨框架组件时提供参考。
🧪 一、Fragment 的真实 DOM 行为
项目 | Vue 3 Fragment | React Fragment |
---|---|---|
是否渲染为 DOM | ❌ 不会渲染为任何 HTML 标签 | ❌ 不会渲染任何标签 |
结构影响 | 真实 DOM 中不产生额外父节点 | 同样不会产生额外父节点 |
插槽结构 | Vue 插槽内部也允许 Fragment | React children 中返回数组或 Fragment |
✅ 示例对比
Vue DOM 结构(组件模板内)
vue
<template>
<h1>Hi</h1>
<p>Bye</p>
</template>
渲染后 DOM 结构:
html
<h1>Hi</h1>
<p>Bye</p>
React DOM 结构
jsx
<>
<h1>Hi</h1>
<p>Bye</p>
</>
渲染后 DOM 结构相同。
⚙️ 二、编译 & 渲染机制底层差异
点位 | Vue 3 | React |
---|---|---|
模板处理方式 | Vue 模板编译为 render 函数,再转为 VNode 树 | JSX 直接转为 React.createElement 调用 |
Fragment 实现 | createVNode(Fragment, ...) ,Fragment 是特殊类型 |
React.Fragment 是一个特殊组件 |
Diff 算法 | 基于 block tree 和优化 patchFlag | Fiber 架构,递归遍历 + 优先级调度 |
✅ 示例:VNode 对象结构
Vue Fragment vnode 示例
ts
{
type: Fragment,
children: [
{ type: 'h1', children: 'Hello' },
{ type: 'p', children: 'World' }
]
}
React Fragment vnode 示例
js
{
type: React.Fragment,
props: {
children: [
{ type: 'h1', props: { children: 'Hello' } },
{ type: 'p', props: { children: 'World' } }
]
}
}
🚀 三、性能对比(渲染效率)
✅ 相同点
- Fragment 本质上都不会带来额外 DOM,DOM 树更轻、更快。
- 两者都避免了冗余
<div>
,在大量渲染场景中可以提升性能。
🔍 不同点
点 | Vue 3 | React |
---|---|---|
静态提升 | Vue 模板编译可分析哪些节点是静态的,进行提升 | JSX 写法需手动避免不必要更新(如 memo 、useMemo ) |
渲染调度 | Vue 是同步递归 + PatchFlag 进行精准更新 | React 使用 Fiber 架构 + 优先级更新 |
Fragment diff 优化 | Vue 在 block tree 中有特殊处理 | React Fragment 会参与 Fiber diff,但性能接近普通节点 |
实测结论(单个 Fragment 中渲染 1 万行元素)
框架 | 首次渲染时间 | 更新耗时 | 内存占用 |
---|---|---|---|
Vue 3 | ✅ 更快初始化(依赖模板优化) | 快速 diff(patchFlag) | 较低 |
React 18 | 稍慢初始化 | 若使用 memo 优化后接近 Vue |
稍高 |
🧭 四、实际应用建议(跨框架组件)
场景 | 推荐策略 |
---|---|
大型组件渲染性能 | Vue 更适合静态模板多的场景;React 需配合 memo / useCallback |
插槽式组件库(如弹窗、表单) | Vue 插槽 + Fragment 更强大(作用域插槽 + 多根支持) |
表格类大数据渲染 | 两者性能接近,但 Vue 可借助 patchFlag 更轻量 |
跨平台 UI 框架 | 建议抽象 Fragment 逻辑,避免过度依赖其结构行为 |
✅ 总结
对比项 | Vue Fragment | React Fragment |
---|---|---|
是否自动启用 | ✅ 是(无须声明) | ❌ 否(需 <></> ) |
是否支持 key | ❌ 不支持(v-for 中需用 template) | ✅ 支持(<Fragment key=""> ) |
插槽支持 | ✅ 强(具名、多根、作用域) | ❌ 无原生插槽机制 |
编译优化 | ✅ 静态提升 + patchFlag | ❌ 靠开发者优化 |
Fiber 架构支持 | ❌ 无(同步渲染) | ✅ 有(支持并发调度) |