Skip to content

透传 Attributes

单根节点的 Attributes 继承

template
<MyButton class="large" />
template
<button>Click Me</button>

渲染出的 DOM 结果是:

template
<button class="large">Click Me</button>

classstyle 的合并

如果一个子组件的根元素已经有了 classstyle 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 对象包含了除组件所声明的 propsemits 之外的所有其他 attribute,例如 classstylev-on 监听器等等。

  • 和 props 有所不同,透传 attributes 在 JavaScript 中保留了它们原始的大小写,所以像 foo-bar 这样的一个 attribute 需要通过 $attrs['foo-bar'] 来访问。
  • @click 这样的一个 v-on 事件监听器将在此对象下被暴露为一个函数 $attrs.onClick

基于 MIT 许可发布