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 不会包含
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)
}
}