inheritAttrs 是 Vue 中的一个选项,我从来没有使用过,或者说我没有仔细观察过某些情况下的异常状况,所以没有注意到它,而文档中对其功能的解释乍一看又让我觉得有些不明所以:
默认情况下父作用域的不被认作 props 的特性绑定 (attribute bindings) 将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。当撰写包裹一个目标元素或另一个组件的组件时,这可能不会总是符合预期行为。通过设置 inheritAttrs 到 false,这些默认行为将会被去掉。而通过 (同样是 2.4 新增的) 实例属性 $attrs 可以让这些特性生效,且可以通过 v-bind 显性的绑定到非根元素上。
这篇文章就来聊一聊这个 inheritAttrs 是做什么的。
示例
通过一个示例,能够非常清晰的了解 inheritAttrs 的功能。
子组件
创一个子组件 son,内容仅仅只是一个简单的输入框,将它的 type 设为 text。
<template>
<input id="message" v-model="message" type="text">
</template>
<script>
export default {
name: "son",
data() {
return {
message: "this is a message"
};
},
methods: {}
};
</script>
<style scoped>
</style>
父组件
创建一个父组件 parent,在父组件中引入子组件并使用,在使用的时候为其添加一个属性 type,并将其值设置为 number。
<template>
<div>
<son type="number"></son>
</div>
</template>
<script>
import son from "./son";
export default {
data() {
return {};
},
components: {
son
}
};
</script>
<style scoped>
</style>
这里并不是向子组件传递参数,因为我并没有在子组件中设置任何 props。
效果
接着在 App.vue 中使用这个 parent 组件:
<template>
<div id="app">
<parent></parent>
</div>
</template>
<script>
import parent from "./components/parent";
export default {
name: "App",
components: {
parent
}
};
</script>
<style>
</style>
运行示例,打开浏览器,页面上的内容将会是下面的样子:

原本在子组件 son 中设置的 input 的类型 text 变成了 number!
如果在 input 标签外包裹上一些标签:
<template>
<div>
<label for="message">
<input id="message" v-model="message" type="text">
</label>
<p>the message is:{{message}}</p>
</div>
</template>
input 的类型又变回了 text:

通过审查元素可以看到,子组件中最外层的 div 多了一个属性 type,其值为 number,恰好就是在父组件中添加的属性。

这就是文档中所说的:
默认情况下父作用域的不被认作 props 的特性绑定 (attribute bindings) 将会“回退”且作为普通的 HTML 特性应用在子组件的根元素上。
div 元素本身并没有 type 属性,所以在父组件中添加的 type="number" 到了它身上也没有影响,但如果是 input 这类本身具有 type 属性的元素,最终得到的效果就很有可能不是我们想要的。
当然,多数情况下,我们并不太可能会创建一个根元素为 input 的组件,但如果元素上多一个这样的属性出来也会让人好奇它的作用。
因此,Vue 提供了 inheritAttrs。
使用 inheritAttrs
改造子组件,为其添加 inheritAttrs 选项,并将其值设为 false:
<script>
export default {
name: "son",
inheritAttrs: false,
data() {
return {
message: "this is a message"
};
},
methods: {}
};
</script>
再次审查元素:

可以看到,type="number" 没有出现在子组件的根元素上了,这样就能很好的减少错误的产生。
另外需要注意的是,这个选项不影响 class 和 style 绑定。
结语
inheritAttrs 在创建组件的时候是非常有帮助的,尤其是当组件非常多,且不同组件间中包含同名 props 的时候,能够避免很多意外情况的发生,很贴心。
