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>

运行示例,打开浏览器,页面上的内容将会是下面的样子:

result

原本在子组件 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

with label

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

inspect element

这就是文档中所说的:

默认情况下父作用域的不被认作 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>




 







再次审查元素:

with inheritAttrs

可以看到,type="number" 没有出现在子组件的根元素上了,这样就能很好的减少错误的产生。

另外需要注意的是,这个选项不影响 classstyle 绑定。

结语

inheritAttrs 在创建组件的时候是非常有帮助的,尤其是当组件非常多,且不同组件间中包含同名 props 的时候,能够避免很多意外情况的发生,很贴心。

最近更新:
作者: MeFelixWang