「这是我参与2022首次更文挑战的第27天,活动详情查看:2022首次更文挑战」。
非 prop 的 attribute
什么是非 prop 的 attribute 呢?
- 当我们传递给一个组件某个属性,但是该属性并没有在
props或emits中进行相应地定义时,我们就称该属性为非prop的attribute; - 常见的例子包括
class、style、id属性等;
我们可以通过 $attrs 属性(property)访问那些非 prop 的属性(attribute)。
我们知道,class 是原生 HTML 元素(如 <div>)上都有的属性(attribute),但是在我们自定义的 Vue 组件上原本可没有 class 属性(attribute),所以如果在一个 Vue 组件上传递了 class 属性,那么默认情况下(没有在该组件中定义这个 class)这个 class 属性就会成为非 prop 的 attribute。
那么,如果我们给一个组件传递了一个非 prop 的 attribute,Vue 会分成 3 种情况来处理:
- 默认情况,即组件只有一个根节点时;
- 禁用
attribute继承时; - 存在多个根节点时;
attribute 继承
当组件有单个根节点时,非 prop 的 attribute 将自动添加到根节点的 attribute 中。
举个例子:
假如 ShowMessage.vue 组件中的模板是这样的:
<template>
<div>
<h2>{{ title }}</h2>
<p>{{ content }}</p>
</div>
</template>
这时 ShowMessage.vue 组件就只有一个根节点(<div>),那么在 App.vue 组件中使用 ShowMessage.vue 组件时,如果传入了 class 属性:
那么最后的效果是这个 class 属性会被添加到 ShowMessage.vue 组件的根节点上:
所以,对于单个根节点的组件,其根节点会默认继承传过来的非 prop 的 attribute。
禁用 attribute 继承
但有时候我们可能不希望组件的根元素自动继承 attribute,那么我们可以在组件中设置 inheritAttrs: false:
- 禁用
attribute继承的常见情况是需要将attribute应用于根元素之外的其它元素; - 我们可以通过
$attrs来访问所有的非props的attribute;
当然,如果有多个 attribute 传入,比如除了 class,还有 id:
那么我们除了可以一个一个绑定:
还可以使用 v-bind 一次性全部绑定:
两种方式的效果是一样的:
多个根节点上的 attribute 继承
多个根节点的 attribute 如果没有显式地绑定:
那么控制台会报警告:
我们必须在目标元素上进行手动绑定: