透传 Attributes

来源: 2024-05-26 06:11:44 播报

Attributes 继承

“透传 attribute”指的是传递给一个组件,却没有被该组件声明为 props 或 emits 的 attribute 或者 v-on 事件监听器。最常见的例子就是 class、style 和 id。

当一个组件以单个元素为根作渲染时,透传的 attribute 会自动被添加到根元素上。

示例:

<!-- <MyButton> 的模板 -->
<button>Click Me</button>
<!-- 父组件 -->
<MyButton class="large" />

结果:

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

对 class 和 style 的合并

如果一个子组件的根元素已经有了 class 或 style attribute,它会和从父组件上继承的值合并。

示例:

<!-- <MyButton> 的模板 -->
<button class="btn">Click Me</button>
<!-- 父组件 -->
<MyButton class="large" />

结果:

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

v-on 监听器继承

click 监听器会被添加到 MyButton 的根元素,即那个原生的 button 元素之上。当原生的 button 被点击,会触发父组件的 onClick 方法。同样的,如果原生 button 元素自身也通过 v-on 绑定了一个事件监听器,则这个监听器和从父组件继承的监听器都会被触发。

<MyButton @click="onClick" />

深层组件继承

组件会在根节点上渲染另一个组件。也就是说子组件接收的透传 attribute 会直接继续传给它的子组件。

示例:

<!-- <MyButton/> 的模板,只是渲染另一个组件 -->
<BaseButton />

注意:

1、透传的 attribute 不会包含 上声明过的 props 或是针对 emits 声明事件的 v-on 侦听函数。

2、透传的 attribute 若符合声明,也可以作为 props 传入

禁用 Attributes 继承

不想要一个组件自动地继承 attribute,我们可以在组件选项中设置 inheritAttrs: false。

在 script setup 中使用 defineOptions。

示例:

<script setup>
defineOptions({
  inheritAttrs: false
})
// ...setup 逻辑
</script>

透传进来的 attribute 可以在模板的表达式中直接用 $attrs 访问到。它含了除组件所声明的 props 和 emits 之外的所有其他 attribute。

如果要透传 attribute 都应用在内部元素上而不是外层的根元素。我们可以通过设定 inheritAttrs: false 和使用 v-bind="$attrs" 来实现。

示例:

<div class="btn-wrapper">
  <button class="btn" v-bind="$attrs">Click Me</button>
</div>

多根节点的 Attributes 继承

子组件中含有多个根元素需要使用 $attrs 绑定穿透到哪个根元素上,不然会抛出一个警告。

示例:

<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>

在 JavaScript 中访问透传 Attributes

1、在 script setup 中使用 useAttrs() 访问组件的所有透传 attribute。

示例:

<script setup>
import { useAttrs } from 'vue'

const attrs = useAttrs()
</script>

2、在setup() 方法中访问组件的所有透传 attribute。

export default {
  setup(props, ctx) {
    // 透传 attribute 被暴露为 ctx.attrs
    console.log(ctx.attrs)
  }
}