主题
透传 Attributes
单根节点的 Attributes 继承
template
<MyButton class="large" />template
<button>Click Me</button>渲染出的 DOM 结果是:
template
<button class="large">Click Me</button>对 class 和 style 的合并
如果一个子组件的根元素已经有了 class 或 style attribute,它会和从父组件上继承的值合并。
template
<MyButton class="large" />template
<button class="btn">Click Me</button>渲染出的 DOM 结果是:
template
<button class="btn large">Click Me</button>v-on 监听器继承
同样的规则也适用于 v-on 事件监听器:
template
<MyButton @click="onClick" />click 监听器会被添加到 <MyButton> 的根元素,即那个原生的 <button> 元素之上。当原生的 <button> 被点击,会触发父组件的 onClick 方法。同样的,如果原生 button 元素自身也通过 v-on 绑定了一个事件监听器,则这个监听器和从父组件继承的监听器都会被触发。
深层组件继承
有些情况下一个组件会在根节点上渲染另一个组件。
template
<!-- 父组件 -->
<MyButton @click="onClick" />
<!-- MyButton -->
<BaseButton />
<!-- BaseButton -->
<button>Click Me</button>- 透传的 attribute 不会包含
<MyButton>上声明过的 props 或是针对 emits 声明事件的v-on侦听函数,换句话说,声明过的 props 和侦听函数被<MyButton>“消费”了。 - 透传的 attribute 若符合声明,也可以作为 props 传入
<BaseButton>。
多根节点的 Attributes 继承
在多个根节点的情况下,如果 $attrs 没有被显式绑定,将会抛出一个运行时警告。
$attrs 被显式绑定,则不会有警告:
template
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>禁用 Attributes 继承
用于控制是否启用默认的组件 attribute 透传行为。
js
defineOptions({
inheritAttrs: false,
})获取透传的 Attributes
- 透传的 attributes 可以在模板中通过
$attrs访问: - 透传的 attributes 可以在
script setup中通过useAttrs函数获取。
vue
<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
</script>
<template>
<span>Fallthrough attribute: {{ $attrs }}</span>
<span>Fallthrough attribute: {{ attrs }}</span>
</template>提示
这个 $attrs 对象包含了除组件所声明的 props 和 emits 之外的所有其他 attribute,例如 class,style,v-on 监听器等等。
- 和 props 有所不同,透传 attributes 在 JavaScript 中保留了它们原始的大小写,所以像
foo-bar这样的一个 attribute 需要通过$attrs['foo-bar']来访问。 - 像
@click这样的一个 v-on 事件监听器将在此对象下被暴露为一个函数$attrs.onClick。
