结论先行:
透传 Attributes 也叫 属性继承。
指的是将在父组件中定义的属性会传递给子组件,不需要在子组件中声明 props。
透传的属性会自动被添加到根元素上。
如果子组件不是以单个元素为根,那么就要使用 v-bind="$attrs" 来绑定透传的属性;
在组件选项中设置 inheritAttrs: false 就可以禁用 attribute 继承;
在 Vue3 中,使用 useAttrs()
访问一个组件的所有透传 attribute;
具体分析:
1、概念
透传 Attributes 也叫 属性继承。
指的是将在父组件中定义的属性会传递给子组件,子组件中不需要声明 props 或者 emit 。
前提:子组件是以单个元素为根作渲染时, 透传的 attribute 会自动被添加到根元素上。
2、例子
常见的例子就是透传 class / style / id 等
<MyButton>
并没有将class
声明为一个它所接受的 prop,所以class
被视作透传 attribute,自动透传到了<MyButton>
的根元素上。
若子组件的根元素上已经有了 class 属性,那它会和从父组件上继承的值合并。
// 父组件
<MyButton class="large" />
// 子组件 MyButton 最后渲染的结果
<button class="large">click me</button>
如果父组件传入属性,子组件中声明了相同的属性。那么写在最下面的属性生效。
例如,不管父组件传入的属性 allow-clear 是 true 还是 false,生效的都是 true
3、 禁用 Attributes 继承
在组件选项中设置 inheritAttrs: false 就可以禁用 attribute 继承
① 场景
最常见的需要禁用 Attributes 继承的场景就是 attribute 需要应用在根节点以外的其他元素上。也就是控制透传进来的 attribute 被如何使用。
② 如何访问
这些透传进来的 attribute 可以在模板的表达式中直接用 $attrs
访问到。
通过
$attrs['foo-bar']
或者 $attrs.onClick 来访问
<span>Fallthrough attribute: {{ $attrs }}</span>
如果透传 attribute 都应用在内部的 <button>
上,而不是外层的 <div>
上。
我们可以通过 设定 inheritAttrs: false
和使用 v-bind="$attrs"
来实现
<div class="btn-wrapper">
<button class="btn" v-bind="$attrs">click me</button>
</div>
4、在 JavaScript 中访问透传 Attributes
使用 useAttrs()
来访问一个组件的所有透传 attribute:
<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
</script>
如果没有使用 <script setup>
,attrs
会作为 setup()
上下文对象的一个属性暴露:
export default {
setup(props, ctx) {
// 透传 attribute 被暴露为 ctx.attrs
console.log(ctx.attrs)
}
}
需要注意的是,这里的透传的属性不是响应式的,因此不能通过侦听器去监听它的变化。
如果需要响应性,可以使用 props