Vue3 转 React:组件透传 Attributes 与 useAttrs 使用详解|VuReact 实战

在 Vue3 迁移 React、跨框架组件封装的场景里,透传 Attributes 是几乎必用、但极易踩坑的能力。Vue 的 $attrs / useAttrs 和 React 的 props 体系设计差异很大,而 VuReact 作为稳定的 Vue3 → React 编译工具,已经把这套逻辑做了完整对齐。

本文带你一次性搞懂:透传属性是什么、为什么必须用 useAttrs、TS 怎么写、转换后长什么样,直接复制就能用。


一、先搞懂:透传 Attributes 到底是什么?

1. Vue 官方定义

透传 attribute :传给组件,但没有被声明为 props / emits 的属性或事件监听器。 最常见:classstyleid、自定义属性、v-on 监听等。

Vue 默认会把它们自动继承到组件根节点 ,也可以用 $attrsuseAttrs() 手动控制。

2. React 里的等价逻辑

React 没有"透传"这个名词,但行为一致: 所有没在 Props 里定义的属性,都属于"透传属性" ,全部挂在 props 上。

区别是:

  • Vue:运行时自动处理
  • React + TS:必须显式写类型,否则报错

3. VuReact 的核心适配规则

VuReact 把透传属性统一理解为: 无类型约束的运行时对象 + 已声明 Props 合并 = 最终组件属性

  • 组件无 Props → 自动生成:props: Record<string, unknown>
  • 组件有 Props → 自动交叉类型:Props & Record<string, unknown>

二、关键:必须从 $attrs 转向 useAttrs()

Vue 里有两种写法:

  • $attrs:运行时隐式变量 → VuReact 无法静态分析
  • useAttrs():显式 API → VuReact 完美支持、推荐唯一写法

1. Vue 中标准 useAttrs 写法(必背)

html 复制代码
<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
</script>

好处:

  • 编译器可静态识别
  • 支持 TS 类型注解
  • 符合 React"显式优于隐式"的习惯

2. VuReact 转换规则(一张表看懂)

Vue useAttrs 写法 React 转换结果
无类型 const attrs = props as Record<string, unknown>
类型断言 as Attrs const attrs = props as Attrs
变量带类型 attrs: Attrs const attrs = props as Attrs
搭配 defineProps Props & Record<string, unknown>

三、实战示例:从 Vue 到 React 完整对照

示例 1:基础用法(无 TS)

Vue 输入

html 复制代码
<template>
  <div :class="attrs.class" :style="attrs.style">
    {{ attrs.title }}
  </div>
</template>

<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
</script>

React 输出

tsx 复制代码
import { memo } from 'react'

const Comp = memo((props: Record<string, unknown>) => {
  const attrs = props as Record<string, unknown>

  return (
    <div className={attrs.class} style={attrs.style}>
      {attrs.title}
    </div>
  )
})

export default Comp

示例 2:TS 类型增强(企业级推荐)

Vue 输入

html 复制代码
<template>
  <div :class="attrs.class" :style="attrs.style">
    {{ attrs.customTitle }}
  </div>
</template>

<script setup lang="ts">
import { useAttrs } from 'vue'

interface CustomAttrs {
  class?: string
  style?: React.CSSProperties
  customTitle?: string
  [key: string]: unknown
}

const props = defineProps<{
  id: string
}>()

const attrs = useAttrs() as CustomAttrs
</script>

React 输出

tsx 复制代码
import { memo } from 'react'

interface CustomAttrs {
  class?: string
  style?: React.CSSProperties
  customTitle?: string
  [key: string]: unknown
}

type ICompProps = { id: string }

const Comp = memo((props: ICompProps & Record<string, unknown>) => {
  const attrs = props as CustomAttrs

  return (
    <div className={attrs.class} style={attrs.style}>
      {attrs.customTitle}
    </div>
  )
})

export default Comp

示例 3:动态属性 / 可选链(真实业务常用)

Vue 输入

html 复制代码
<template>
  <div
    :class="[
      'base',
      attrs.class,
      attrs.xx?.class,
      attrs['custom-class']
    ]"
  >
    {{ attrs?.xxx?.content }}
  </div>
</template>

React 输出

tsx 复制代码
import { memo } from 'react'
import { dir } from '@vureact/runtime-core'

const Comp = memo((props: Record<string, unknown>) => {
  const attrs = props

  return (
    <div
      className={dir.cls([
        'base',
        attrs.class,
        attrs.xx?.class,
        attrs['custom-class']
      ])}
    >
      {attrs?.xxx?.content}
    </div>
  )
})

四、避坑指南(VuReact 必看)

  1. 必须用 useAttrs(),禁止用 $attrs 编译器无法分析运行时变量,会丢属性。

  2. TS 尽量写接口 有利于提示、重构、避免空值报错。

  3. class/style 自动适配 classclassName style → 自动适配 React.CSSProperties

  4. defineProps + useAttrs 会自动合并类型 不用手动改。

  5. JS 项目直接用 会被编译成 const attrs = props,完全兼容。


五、总结

VuReact 处理透传 Attributes 的核心思想只有一句话: 把 Vue 隐式的 $attrs 变成显式的 useAttrs,再映射到 React 的 props 体系。

  • 你只管按 Vue 官方写法写
  • 编译器自动转成标准 React TSX
  • 类型安全、生产可用、迁移成本极低

正在做 Vue3 → React 迁移的同学,这套透传方案可以直接进团队规范。


🔗 相关资源


推荐阅读

#Vue3 #React #Vue转React #VuReact #前端迁移 #useAttrs #组件封装 #TypeScript

相关推荐
光影少年1 小时前
reeact虚拟DOM、Diff算法原理、key的作用与为什么不能用index
前端·react.js·掘金·金石计划
你真的快乐吗1 小时前
@fuxishi/svg-icon:一个 Vue 3 svg本地图标+iconify图标组件库,让图标管理不再头疼
前端·vue.js·typescript
江南十四行1 小时前
ReAct Agent 基本理论与项目实战(二)
前端·react.js·前端框架
吴声子夜歌2 小时前
Vue3——脚手架Vite
前端·javascript·vue.js·vite
摘星编程2 小时前
当AI开始学会“使用工具“——从ReAct到MCP,大模型如何获得真正的行动力
前端·人工智能·react.js
rADu REME3 小时前
SpringBoot + vue 管理系统
vue.js·spring boot·后端
啊哈一半醒4 小时前
React 核心知识点系统总结:从基础语法到高级 API,一篇文章梳理完整学习路线
javascript·学习·react.js
被考核重击5 小时前
Vue响应式原理(下)
前端·javascript·vue.js
前端摸鱼匠15 小时前
Vue 3 的v-bind合并行为:讲解v-bind与普通属性合并的规则
前端·javascript·vue.js·前端框架·ecmascript
Python私教1 天前
Pure-Admin-Thin 深度解析:完整版和精简版到底怎么选?
vue.js·人工智能·开源