Vue Fragment vs React Fragment

文章目录

  • 前言
    • [🧩 一、概念对比: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() 渲染列表

    js 复制代码
    items.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 写法需手动避免不必要更新(如 memouseMemo
渲染调度 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 架构支持 ❌ 无(同步渲染) ✅ 有(支持并发调度)

相关推荐
GISer_Jing1 小时前
Monorepo+Pnpm+Turborepo
前端·javascript·ecmascript
天涯学馆1 小时前
前端开发也能用 WebAssembly?这些场景超实用!
前端·javascript·面试
我在北京coding2 小时前
TypeError: Cannot read properties of undefined (reading ‘queryComponents‘)
前端·javascript·vue.js
海天胜景3 小时前
vue3 获取选中的el-table行数据
javascript·vue.js·elementui
翻滚吧键盘3 小时前
vue绑定一个返回对象的计算属性
前端·javascript·vue.js
苦夏木禾3 小时前
js请求避免缓存的三种方式
开发语言·javascript·缓存
超级土豆粉3 小时前
Turndown.js: 优雅地将 HTML 转换为 Markdown
开发语言·javascript·html
乆夨(jiuze)4 小时前
记录H5内嵌到flutter App的一个问题,引发后面使用fastClick,引发后面input输入框单击无效问题。。。
前端·javascript·vue.js
小彭努力中4 小时前
141.在 Vue 3 中使用 OpenLayers Link 交互:把地图中心点 / 缩放级别 / 旋转角度实时写进 URL,并同步解析显示
前端·javascript·vue.js·交互