$attrs学习
一、什么是 $attrs
$attrs 用于实现当前组件的父组件,向当前组件的子组件通信(祖 ↔ 孙),也是一种通信方式。
具体说明:$attrs 是一个对象,包含所有父组件传入的标签属性。
注意:$attrs4 会自动排除 props 中声明的属性(可以认为声明过的 props 被子组件自己“消费”了)
在 Vue 3 中,$attrs 是一个非常有用的特性,它包含了组件的所有“非 props”属性和事件。这对创建泛用组件(如包装器组件或高阶组件)非常有帮助,允许将未声明的属性自动传递给子组件。
使用场景
- 创建包装组件,允许将原始组件的属性直接传递下去。
- 处理动态属性的情况,而不必逐个声明 props。
- 结合
v-bind="$attrs"
自动绑定属性。
<!-- 父组件 -->
<ChildComponent name="张三" age="18" title="学生" /><!-- 子组件 ChildComponent -->
<script>
export default {props: ['name'] // 只声明接收了 name,但是还有 age,title没有被接收
} // 此时子组件的 $attrs 会是:{ age: '18', title: '学生' }
</script>
二、v-bind="$attrs" 的作用
v-bind="$attrs"
等价于将 $attrs
中的所有属性通过 v-bind
批量绑定到某个元素或子组件上,实现属性的 “透传”。结合 v-bind="$attrs"自动绑定属性。
<!-- 写法1:手动绑定:将剩下的两个属性 手动绑定 -->
<GrandChildComponent :age="age" :title="title" /><!-- 写法2:使用 $attrs 批量绑定 直接使用 $attrs -->
<GrandChildComponent v-bind="$attrs" />
三、流程示例
当需要跨多层组件传递属性时,v-bind="$attrs"
可以避免逐层手动传递 props
,简化代码。深层次的传递参数时好用。
<!-- 父组件 Parent -->
<template><div><!-- 向子组件传递3个属性 --><ChildComponent name="张三" age="18" title="学生" /> // 子组件</div>
</template><!-- 子组件 ChildComponent -->
<template><div><!-- 子组件不关心 age 和 title,通过 $attrs 透传给孙组件 --><GrandChildComponent v-bind="$attrs" /> // 孙组件</div>
</template>
<script>
export default {props: ['name'], // 子组件只接收 name,其余属性会进入 $attrsmounted() {console.log(this.$attrs); // { age: '18', title: '学生' }}
}
</script><!-- 孙组件 GrandChildComponent -->
<template><div><p>年龄:{{ age }}</p><p>标题:{{ title }}</p></div>
</template>
<script>
export default {props: ['age', 'title'] // 直接接收透传过来的属性
}
</script>
流程梳理:
- 父组件向
ChildComponent
传递name
、age
、title
三个属性。 ChildComponent
只通过props
接收name
,剩余的age
和title
自动存入$attrs
。ChildComponent
通过v-bind="$attrs"
将$attrs
中的属性批量传递给GrandChildComponent
。GrandChildComponent
通过props
接收age
和title
,完成属性透传。
本质流程:
父组件传递属性 → 中间组件通过 $attrs
收集未声明的属性 → 用 v-bind="$attrs"
透传给子组件 → 子组件通过 props
接收。
通过这种方式,可以避免在中间组件中冗余声明不需要的 props
,让代码更简洁、维护性更高。