在 Vue 3 项目中封装组件时,$attrs 的作用是收集和传递那些未被组件自身 props 接收的属性。
它是 Vue 3 组合式 API 中一个非常重要的概念,用于实现组件的透明属性传递(Attribute Fallthrough)。
props 选项中声明接收这些属性,那么这些属性默认会作为一个对象被收集到子组件实例的 $attrs 属性中。在 Vue 3 中,如果一个组件只有一个根元素,并且你没有在 <script setup> 中使用 inheritAttrs: false 或者在 options API 中设置 inheritAttrs: false,那么 $attrs 中的所有属性(包括 class 和 style)都会自动应用到该根元素上。
例如:
> <MyButton type="submit" data-test="btn" class="large-btn" />
inheritAttrs: false在封装复杂或多根节点的组件时,通常需要禁用自动属性继承,然后通过 v-bind="$attrs" 手动将属性传递给组件内部的特定元素。
如何设置:
<script setup> 中:
defineOptions({
inheritAttrs: false
})
export default {
inheritAttrs: false,
// ...
}
$attrs当你设置了 inheritAttrs: false 或组件是多根节点时,你需要使用 v-bind="$attrs" 来手动绑定这些未被接收的属性到你指定的元素上。
应用场景:
多根节点组件: Vue 无法确定将属性应用到哪个根元素,因此必须手动绑定。
将属性传递给内部深层元素: 例如,将 aria-label 传递给组件内部的 <input> 而不是外部的 <div>。
示例(禁用继承后手动绑定):
> <template> <div class="input-wrapper"> <label>{{ label }}</label> <input type="text" v-bind="$attrs"> > </div> </template>
| API 风格 | 访问方式 |
|---|---|
| Options API | this.$attrs |
| Composition API (Setup 函数) | const attrs = useAttrs() |
Composition API (<script setup>) | const attrs = useAttrs() |
props 的区别props:用于组件期望接收的数据,需要在 props 选项中显式声明,声明后 Vue 会进行类型检查、默认值设置等。$attrs:用于组件未声明接收的属性(通常是 HTML 原生属性或第三方库需要的属性),它是一个纯粹的对象,不会触发组件的更新(除非你通过 v-bind="$attrs" 使用了它)。on- 开头)也被包含在 $attrs 对象中。<MyComponent @click="handleClick" />,那么 $attrs 中将包含一个键值对:{ onClick: handleClick }。当你使用 v-bind="$attrs" 时,这些事件监听器也会被正确地绑定到目标元素上。class 和 styleclass 和 style 属性也会被包含在 $attrs 中。class 和 style 与子组件根元素自身的 class 和 style。