Vue组件属性透传是根据声明、禁用及单根等条件,自动或手动决定未声明属性($attrs)的落点与共存方式;单根组件默认透传并智能合并class/style,覆盖普通属性,透传v-on监听器;多根或非根绑定需手动关闭inheritAttrs并useAttrs选择性绑定;属性覆盖优先级由绑定位置和方式决定;透传逐层继承,任一层禁用或声明即中断。

Vue 组件的属性透传不是“把父组件的属性复制过去”,而是根据是否声明、是否禁用、是否单根等条件,自动或手动决定这些未声明属性($attrs)最终落到哪个 DOM 元素上,以及如何与已有属性共存。
单根组件默认透传行为
子组件只有一个根元素,且未设置 inheritAttrs: false 时,父组件传入但未在 defineProps 中声明的属性会自动绑定到该根元素:
-
class 和 style 会智能合并:子组件根元素写
class="btn",父组件传class="primary large",最终是class="btn primary large" -
普通属性直接覆盖:根元素已有
id="inner",父组件传id="outer",结果取id="outer" -
v-on 监听器也会透传:父组件的
@click="handle"会绑定到根元素;若根元素自身也有@click,两个监听器都会执行
多根或非根绑定必须手动处理
子组件有多个根节点(Fragment),或需要把属性传给内部非根元素(比如封装 <el-input> 时想把 placeholder 交给内部 <input>),就不能依赖自动透传:
使用 JSON Schema 验证 JSON 数据,从示例 JSON 生成 schema,并将其转换为 TypeScript 接口、Python 数据类或 Markdown 文档。
- 需先在
<script setup>中调用defineOptions({ inheritAttrs: false })关闭自动透传 - 再用
const attrs = useAttrs()获取透传对象 - 模板中可选择性绑定:
<input :placeholder="attrs.placeholder" :class="attrs.class"> - 注意大小写:父组件传
data-test-id="123",需通过attrs['data-test-id']访问
属性覆盖优先级取决于绑定方式和时机
透传值是否生效,不只看“谁后传”,更要看它绑定在什么位置、用什么方式绑定:
立即学习“前端免费学习笔记(深入)”;
- 模板中静态写的
class="fixed"和透传的class="dynamic"会合并,不是覆盖 - 但
id、name这类不支持合并的属性,透传值会覆盖模板中的静态值 - 如果同时用了
v-bind:id="computedId"和$attrs.id,以v-bind表达式为准(动态绑定优先) - 已在 emits 中声明的事件(如
emits: ['click'])不会进入$attrs,也就不会被透传
深层嵌套中透传是逐层继承,不是跳过中间层
A → B → C 结构中,A 传 data-role="submit" 给 B:
- B 未声明该 prop 且未禁用透传 → 属性自动挂到 B 的根元素上
- 若 B 的根是一个组件 C,且 C 同样未声明
data-role、未禁用透传 → 该属性会继续透传到 C 的根元素 - 只要任一层设置了
inheritAttrs: false或声明了对应 prop,透传链就在此中断

















