核心概念
inheritAttrs 是 Vue 3 中用于控制组件是否继承非 props 属性的选项。其默认值为 true,表示未被声明为 props 的属性会自动绑定到组件的根元素上。若设置为 false,这些属性将被忽略,开发者需手动通过 $attrs 显式绑定。该属性常用于解决组件样式污染、事件冲突等场景。
基础语法
禁用自动继承
export default {
inheritAttrs: false,
setup(props, { attrs }) {
// 非props属性将不再自动绑定
// 通过 attrs 对象访问 $attrs
}
}
手动绑定非props属性
<template>
<div v-bind="$attrs">
<!-- 手动将非props属性绑定到特定元素 -->
</div>
</template>
默认继承行为
<template>
<!-- 无需手动绑定,非props属性自动添加到根元素 -->
<MyComponent class="custom-style" @click="handleClick" />
</template>
进阶特性
与 v-model 的组合使用
<script setup>
defineProps(['modelValue']) // 显式声明 props
</script>
<template>
<input v-model="modelValue" v-bind="$attrs" />
<!-- 当使用 v-model 时,需显式声明 props 并手动绑定 $attrs -->
</template>
动态类名处理
<template>
<div :class="[$attrs.class, 'base-style']">
<!-- 合并父组件传来的 class 与本地样式 -->
</div>
</template>
与 props 的对比表
| 属性类型 | 继承方式 | 绑定位置 | 优先级 |
|---|---|---|---|
| props | 显式声明 | 根元素/内部元素 | 高 |
| $attrs | inheritAttrs 控制 | 根元素或手动绑定 | 低 |
实战应用
表单组件开发
<template>
<input v-bind="$attrs" :value="value" @input="$emit('input', $event.target.value)" />
</template>
<script setup>
defineProps(['value'])
</script>
<!-- 父组件使用 -->
<MyInput v-model="form.name" class="form-control" required />
自定义按钮组件
<script setup>
defineProps({
type: String,
disabled: Boolean
})
</script>
<template>
<button v-bind="$attrs" :type="type" :disabled="disabled">
<slot></slot>
</button>
</template>
<!-- 父组件使用 -->
<MyButton @click="submitForm" class="btn-primary" />
注意事项
- ❗ 忘记关闭 inheritAttrs 时,未声明的 props 会覆盖子组件的根元素属性
- ❗ $attrs 与 props 同名时,props 优先级更高
- ❗ 高频使用时应考虑性能影响(频繁属性扩散)
- ❗ 不建议与原生 HTML 属性混用(如 class/id 同名时易冲突)
正确设置 inheritAttrs 可以避免组件间属性污染,建议在需要精确控制属性绑定的场景中设置为 false。