vue3 透传 Attributes
前言
Vue 3 现在正式支持了多根节点的组件,也就是片段!
Vue 2.x 遵循单根节点组件的规则,即一个组件的模板必须有且仅有一个根元素。
为了满足单根节点的要求,开发者会将原本多根节点的内容包裹在一个<div>元素中:
<!-- Layout.vue -->
<template><div><h1>标题</h1><p>段落</p></div>
</template>
这是因为Vue 的编译器在解析组件模板时,是基于单根节点的树形结构进行处理的。如果存在多个根节点,编译器无法明确地构建组件的虚拟 DOM 结构。
因此,在Vue 2.x中,父组件在使用子组件时,写在子组件上的 class、style 和 id 等属性会直接传递到子组件的根元素上。
Vue 3.x 打破了 Vue 2.x 中组件模板必须有且仅有一个根元素的限制,现在组件可以包含多个根节点。
<template><h1>标题</h1><p>段落</p>
</template>
当组件存在多个根节点时,在父组件中给该组件传递属性(attribute)就需要明确指定这些属性应该绑定到哪个根节点上。如果不进行显式指定,Vue 无法确定属性的归属。
<template><ChildComponent><template v-slot:default="{ attrs }"><div v-bind="attrs">这是一个 div 根节点</div><p>这是一个 p 根节点</p><span>这是一个 span 根节点</span></template></ChildComponent>
</template>
在示例中,通过v-slot:default="{attrs}"获取到ChildComponent.vue通过插槽传递给父组件的所有属性(存储在attrs中),然后使用v-bind="attrs"将这些属性显式地绑定到其中一个根节点<div>上。
Attributes 继承
“透传 attribute”指的是传递给一个组件,却没有被该组件声明为 props 或 emits 的 attribute 或者 v-on 事件监听器。
当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上。
最常见的例子就是 class、style 和 id。
子组件ChildComponent.vue的模板内容如下:
<div>这是子组件的div</div>
在父组件使用子组件ChildComponent.vue,并且传入了 class、style 和 id:
<template><div><h1>父组件</h1><ChildComponent class="child-div" id="child-div"style="font-size: 20px; color: brown;" /></div>
</template>
<script setup lang="ts">
import ChildComponent from './ChildComponent.vue';
</script>
渲染出的DOM结果是:
<div class="child-div" id="child-div" style="font-size: 20px; color: brown">这是子组件的div
</div>
<ChildComponent> 并没有将 class、style 和 id声明为它所接受的 prop,所以 class、style 和 id被视作透传 attribute,自动透传到了 <ChildComponent> 的根元素上。
当 style 属性透传到子组件的根元素后,它的生效方式与直接在 HTML 元素上设置 style 属性是一样的:

自动合并 class 或 style
如果一个子组件的根元素已经有了 class 或 style attribute,它会和从父组件上继承的值合并。
给子组件ChildComponent.vue加上class、style、id属性:
<divclass="child-box"id="child-box"style="padding: 15px; background-color: #f8f8f8"
>这是子组件的div
</div>
渲染出的DOM结果是:
<divclass="child-box child-div"id="child-div"style="padding: 15px;background-color: rgb(248, 248, 248);font-size: 20px;color: brown;"
>这是子组件的div
</div>
子组件的class、style 属性值 和 从父组件上继承的值合并,子组件的 id 属性值被从父组件继承的 id 属性值覆盖。
页面渲染结果如下图:

v-on 监听器继承
子组件ChildComponent.vue的模板内容如下:
<div @click="console.log('子组件的点击事件被触发了')"> 这是子组件的div </div>
在父组件中,给<ChildComponent>绑定一个点击事件:
<template><div class="home-wrap"><h1>父组件</h1><ChildComponent @click="console.log('在父组件中,给子组件绑定的点击事件被触发了!')"/></div>
</template>
<script setup lang="ts">
import ChildComponent from './ChildComponent.vue';
</script>
父组件中绑定的click 监听器会被添加到 <ChildComponent> 的根元素:子组件的 <div> 元素之上。
子组件的<div>元素自身也通过 v-on 绑定了一个事件监听器。
当点击子组件的<div>元素,子组件的click监听器和从父组件继承的监听器都会被触发:

深层组件继承
有些情况下一个组件会在根节点上渲染另一个组件。
当ChildComponent.vue的根节点渲染的是另一个组件GrandChild.vue时:
<!-- ChildComponent.vue 的模板,只是渲染另一个组件:<GrandChild /> -->
<template><GrandChild />
</template>
此时 <ChildComponent> 接收的透传 attribute 会直接继续传给 <GrandChild>。
注意:
-
透传的 attribute 不会包含
<ChildComponent>上声明过的 props 或是针对emits声明事件的v-on侦听函数,换句话说,声明过的 props 和侦听函数被<ChildComponent>“消费”了。 -
透传的 attribute 若符合声明,也可以作为 props 传入
<GrandChild>。
禁用 Attributes 继承
在选项式API中,在组件选项中设置 inheritAttrs: false 可以禁止 组件自动地继承 attribute。
在组合式API中,在 <script setup> 中使用 defineOptions:
<script setup>
defineOptions({inheritAttrs: false
})
// ...setup 逻辑
</script>
通过设置 inheritAttrs 选项为 false,可以完全控制透传进来的 attribute 被如何使用。
注意:透传进来的 attribute 可以在模板的表达式中直接用 $attrs 访问到。
在ChildComponent.vue中,设置 inheritAttrs: false 并通过$attrs访问透传属性 customValue:
<!-- ChildComponent.vue 的模板 -->
<template><div>在ChildComponent.vue中,读取透传 Attributes: {{ $attrs.customValue }}</div>
</template>
<script setup lang="ts">
defineOptions({inheritAttrs: false
})
</script>
在父组件中,使用子组件ChildComponent.vue,传递class属性、customValue属性:
<template><div class="home-wrap"><h1>父组件</h1><ChildComponent class="child-div" :customValue="customValue" /></div>
</template>
<script setup lang="ts">
import { ref } from 'vue';
import ChildComponent from './ChildComponent.vue';
const customValue = ref(10)
</script>
渲染出的DOM结果是:
<div>在ChildComponent.vue中,读取透传 Attributes: 10</div>
可以看到,父组件传的class属性并没有被直接透传到子组件的根元素上。
通过Vue Devtools查看$attrs,$attrs 包含了 透传进来的 class、customValue属性:

$attrs 对象包含了除组件所声明的 props 和 emits 之外的所有其他 attribute,例如 class,style,v-on 监听器等等。
-
和
props有所不同,透传 attributes 在 JavaScript 中保留了它们原始的大小写,所以像foo-bar 这样的一个 attribute 需要通过$attrs['foo-bar']来访问。 -
像
@click这样的一个v-on事件监听器将在此对象下被暴露为一个函数$attrs.onClick。
通过设定 inheritAttrs: false 和使用 v-bind="$attrs" 来实现将 透传 attribute 应用在合适的元素上:
<!-- ChildComponent.vue 的模板 -->
<template><div><div v-bind:="$attrs">在ChildComponent.vue中,读取透传 Attributes: {{ $attrs.customValue }}</div></div>
</template>
<script setup lang="ts">
defineOptions({inheritAttrs: false
})
</script>
渲染出的DOM结果是:
<div><div class="child-div" customvalue="10">在ChildComponent.vue中,读取透传 Attributes: 10</div>
</div>
通过不带参数的 v-bind,将一个对象的所有属性都作为 attribute 应用到目标元素上。
多根节点的 Attributes 继承
和单根节点组件有所不同,有着多个根节点的组件没有自动 attribute 透传行为。如果 $attrs 没有被显式绑定,将会抛出一个运行时警告。
修改ChildComponent.vue:
<!-- ChildComponent.vue 的模板 -->
<template><h2>ChildComponent的标题</h2><div>ChildComponent的内容</div>
</template>
此时,ChildComponent.vue是多根节点模板,由于 Vue 不知道要将 attribute 透传到哪里,所以会抛出一个警告:
Extraneous non-props attributes (class, customValue) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.
当ChildComponent.vue有多个根节点时,需要显式绑定 $attrs:
<!-- ChildComponent.vue 的模板 -->
<template><h2 v-bind="$attrs">ChildComponent的标题</h2><div>ChildComponent的内容</div>
</template>
在 JavaScript 中访问透传 Attributes
在选项式API中,attrs 会作为 setup() 上下文对象的一个属性暴露:
<script>
export default {setup(props, ctx) {// 透传 attribute 被暴露为 ctx.attrs,且 没有响应性console.log(ctx.attrs)}
}
</script>
在组合式API中,在 <script setup> 中使用 useAttrs() API 来访问一个组件的所有透传 attribute:
<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
</script>
有个疑问待解决:
官网说法:
attrs对象总是反映为最新的透传 attribute,但它没有响应性,不能通过侦听器去监听它的变化。
我直接在模板中使用$attrs,以及使用上述2种方式获取attrs,修改透传 attribute 后,页面也更新了。
所以没get到,官方说的attrs对象没有响应性是指哪方面。
知道为什么的童鞋可以在评论区讲一下或者是私信给我说一下,非常感谢!
相关文章:
vue3 透传 Attributes
前言 Vue 3 现在正式支持了多根节点的组件,也就是片段! Vue 2.x 遵循单根节点组件的规则,即一个组件的模板必须有且仅有一个根元素。 为了满足单根节点的要求,开发者会将原本多根节点的内容包裹在一个<div>元素中&#x…...
4.接口测试基础(Jmter工具/场景二:一个项目由多个人负责接口测试,我只负责其中三个模块,协同)
一、场景二:一个项目由多个人负责接口测试,我只负责其中三个模块,协同 1.什么是测试片段? 1)就相当于只是项目的一部分用例,不能单独运行,必须要和控制器(include,模块)一…...
electron react离线使用monaco-editor
目录 1.搭建一个 electron-vite 项目 2.安装monaco-editor/react和monaco-editor 3.引入并做monaco-editor离线配置 4.react中使用 5.完整代码示例 6.monaco-editor离线配置官方说明 7.测试 1.搭建一个 electron-vite 项目 pnpm create quick-start/electron 参考链接…...
Python 的 WSGI 简单了解
从 flask 的 hello world 说起 直接讨论 WSGI,很多人可能没有概念,我们还是先从一个简单的 hello world 程序开始吧。 from flask import Flaskapp Flask(__name__)app.route("/", methods[GET]) def index():return "Hello world!&q…...
基于stm32使用ucgui+GUIBuilder开发ui实例
1 项目需求 1.1 基于Tft 触摸屏实现一个自锁按键 1.2 按键在按下后背景色需要进行变化,以凸显当前按键状态(选中or 未选中) 1.3 按键选中时对某一gpio输出低电平,非选中时输出高电平 2 移植 ucgui UCGUI的文件数量很大&#x…...
Spring扩展点系列-ApplicationContextAwareProcessor
文章目录 简介源码分析示例代码示例一:扩展点的执行顺序运行示例一 示例二:获取配置文件值配置文件application.properties内容定义工具类ConfigUtilcontroller测试调用运行示例二 示例三:实现ResourceLoaderAware读取文件ExtendResourceLoad…...
基于Keil软件实现实时时钟(江协科技HAL库)
实时时钟实验是基于江协科技STM32的HAL库工程模板创建的(可以在作品“基于江科大STM32创建的HAL库工程模板”中的结尾处获取工程模板的百度网盘链接) 复制“OLED显示”的工程文件——“4-1 OLED显示屏”,并命名为“12-2 实时时钟 ”。打开工程,把下面的程序复制到相应的文…...
dedecms靶场(四种webshell姿势)
进入靶场 姿势一:过文件管理器上传WebShell 步骤一:登录后台 /dede 步骤二:核心-》文件式管理-》文件上传-》上传一句话木马 点击 步骤三:进行蚁剑连接 姿势二:修改模板文件拿WebShell 步骤一:模板-》默认…...
PHP:强大的Web开发语言
PHP:强大的Web开发语言 一、PHP 简介及优势 PHP 的基本概念 PHP(PHP: Hypertext Preprocessor)即 “超文本预处理器”,是一种通用开源脚本语言,最初由 Rasmus Lerdorf 于 1994 年创建。它可以在服务器上执行…...
06_Python数据类型_元组
Python的基础数据类型 数值类型:整数、浮点数、复数、布尔字符串容器类型:列表、元祖、字典、集合 元组 元组(Tuple)是一种不可变的序列类型,与列表类似,但有一些关键的区别。本质:只读的列表…...
【Vue】- ref获取DOM元素和购物车案例分析
文章目录 知识回顾前言源码分析1. ref2. 购物车案例分析3. 购物车计算、全选 拓展知识数据持久化localStorage 总结 知识回顾 前言 元素上使用 ref属性关联响应式数据,获取DOM元素 步骤 ● 创建 ref > const hRef ref(null) ● 模板中建立关联 > <h1 re…...
【AI大模型】ChatGPT模型原理介绍(下)
目录 🍔 GPT-3介绍 1.1 GPT-3模型架构 1.2 GPT-3训练核心思想 1.3 GPT-3数据集 1.4 GPT-3模型的特点 1.5 GPT-3模型总结 🍔 ChatGPT介绍 2.1 ChatGPT原理 2.2 什么是强化学习 2.3 ChatGPT强化学习步骤 2.4 监督调优模型 2.5 训练奖励模型 2.…...
Python数据分析与可视化实战指南
在数据驱动的时代,Python因其简洁的语法、强大的库生态系统以及活跃的社区,成为了数据分析与可视化的首选语言。本文将通过一个详细的案例,带领大家学习如何使用Python进行数据分析,并通过可视化来直观呈现分析结果。 一、环境准…...
react18基础教程系列-- 框架基础理论知识mvc/jsx/createRoot
react的设计模式 React 是 mvc 体系,vue 是 mvvm 体系 mvc: model(数据)-view(视图)-controller(控制器) 我们需要按照专业的语法去构建 app 页面,react 使用的是 jsx 语法构建数据层,需要动态处理的的数据都要数据层支持控制层: 当我们需要…...
牛客周赛 Round 60 折返跑(组合数学)
题目链接:题目 大意: 在 1 1 1到 n n n之间往返跑m趟,推 m − 1 m-1 m−1次杆子,每次都向中间推,不能推零次,问有多少种推法(mod 1e97)。 思路: 一个高中学过的组合数…...
深入浅出Java匿名内部类:用法详解与实例演示
匿名内部类(Anonymous Inner Class)在Java中是一种非常有用的特性,它允许你在一个类的定义中直接创建并实例化一个内部类,而不需要为这个内部类指定一个名字。匿名内部类通常用于以下几种情况: 实现接口:当…...
数据库MySQL、Mariadb、PostgreSQL、MangoDB、Memcached和Redis详细介绍
以下是一些常见的后端开发数据库选型: 关系型数据库(RDBMS):关系型数据库是最常见的数据库类型,使用表格和关系模型来存储和管理数据。常见的关系型数据库包括MySQL、PostgreSQL和Oracle等。这些数据库适合处理结构化数…...
【ArcGIS Pro实操第七期】栅格数据合并、裁剪及统计:以全球不透水面积为例
【ArcGIS Pro实操第七期】批量裁剪:以全球不透水面积为例 准备:数据下载ArcGIS Pro批量裁剪数据集1 数据拼接2 数据裁剪3 数据统计:各栅格取值3.1 栅格计算器-精确提取-栅格数据特定值3.2 数据统计 4 不透水面积变化分析 参考 准备࿱…...
【Linux】Image、zImage与uImage的区别
1、Image 1.1 什么是 Image Image 是一种未压缩的 Linux 内核镜像文件,包含了内核的所有代码、数据和必要的元信息。它是 Linux 内核在编译过程中生成的一个原始的二进制文件,未经过任何压缩或额外的封装处理。由于未压缩,Image 文件相对较…...
算子加速(3):自定义cuda扩展
需要自定义某个层,或有时候用c++实现你的操作(c++扩展)可能会更好: 例如:需要实现一个新型的激活函数例如: bevfusion用cuda实现bevpool加速自定义扩展的步骤 (1) 首先用纯pytorch和python 实现我们所需的功能,看看效果再决定要不要进一步优化(2) 明确优化方向,用C++ (或CU…...
Apollo配置中心实战:从零到一的Docker化部署与核心配置详解
1. 为什么选择Apollo配置中心 在微服务架构中,配置管理一直是个让人头疼的问题。记得我第一次尝试用传统properties文件管理配置时,光是同步不同环境的配置就浪费了大半天时间。后来接触到Apollo,才发现原来配置管理可以这么优雅。 Apollo作为…...
避开时区陷阱:React Spectrum日期时间处理完全指南
避开时区陷阱:React Spectrum日期时间处理完全指南 【免费下载链接】react-spectrum A collection of libraries and tools that help you build adaptive, accessible, and robust user experiences. 项目地址: https://gitcode.com/GitHub_Trending/re/react-sp…...
从经典控制器到前沿控制的发展
目录 前言 一、PID控制 1.数字PID 2.PID参数的优化 1.微分项的问题 2.积分项的问题 3.PID参数整定法 3.PID参数对系统性能指标的影响 二、模糊控制 1.模糊控制的五大核心步骤 1.模糊化 2.建立模糊规控制规则 3.模糊推理与解模糊 2.模糊PID 1.直接型模糊PID 2.增…...
Java学习——数据类型
目录 一、概述 二、基本数据类型 1、数值型 2、字符型 3、布尔型 三、引用数据类(后期补充) 1、类 2、接口 3、数组 4、枚举 5、注解 四、数据类型转换 1、概述 2、隐式转换(自动类型转换) 3、显式转换(…...
YOLO12与YOLO11对比:新一代模型在精度和速度上有哪些提升?
YOLO12与YOLO11对比:新一代模型在精度和速度上有哪些提升? 1. 引言 目标检测技术作为计算机视觉领域的核心任务之一,其发展一直备受关注。YOLO(You Only Look Once)系列模型因其出色的实时性能而广受欢迎。2025年,Ultralytics推…...
37、三种事件处理方式优先级---------事件系统
三种事件处理方式优先级我们学习了三种是事件处理方式 1重写event函数 2重写具体的事件函数 3重写事件过滤器并安装 那么这三种方式,调用的顺序会怎么样呢? 我们还是在MainWindow中创建一个按钮,然后用三种方式捕获这个按钮的点击事件&#x…...
OpenClaw模型微调:Kimi-VL-A3B-Thinking领域适配数据准备指南
OpenClaw模型微调:Kimi-VL-A3B-Thinking领域适配数据准备指南 1. 为什么需要领域特定数据微调 当我第一次尝试将Kimi-VL-A3B-Thinking模型应用到医疗影像分析场景时,发现模型对专业术语的理解和图像特征的把握都不够精准。这让我意识到,即使…...
深入解析 OpenSTLinux 6.6 Yocto SDK 环境配置与 BSP 源码部署 - STM32MP2 实战(基于STM32CubeMX)
1. OpenSTLinux 6.6 Yocto SDK环境配置全攻略 刚拿到STM32MP2开发板时,最让人头疼的就是搭建开发环境。我花了整整三天时间才把Yocto SDK环境配置明白,今天就把这些实战经验分享给大家,让你少走弯路。 首先需要下载两个关键文件:S…...
MATLAB三维绘图实战:用plot3和fplot3函数搞定螺旋线与墨西哥帽(附完整代码)
MATLAB三维绘图实战:螺旋线与墨西哥帽的视觉盛宴 在工程计算与科学可视化领域,MATLAB始终保持着不可替代的地位。当二维平面无法完整表达数据的内在规律时,三维图形便成为洞察复杂关系的利器。本文将带您深入探索MATLAB中两大三维曲线绘制神器…...
告别命令行恐惧:用Docker Compose 5分钟拉起一个开箱即用的Yapi服务
告别命令行恐惧:用Docker Compose 5分钟拉起一个开箱即用的Yapi服务 在API开发协作中,Yapi作为一款优秀的接口管理工具,能显著提升团队效率。但传统部署方式往往让人望而却步——需要手动安装MongoDB、配置Node.js环境、解决Python依赖&#…...
