Skip to content

透传 Attributes

"透传 Attributes" 是指父组件传递给子组件的属性,但是子组件没有通过 props emits 等方式去接收,最终属性会被渲染到子组件的根元素上。

单个根节点 Attributes 继承

例如父组件 index.vue 向子组件 MyButton.vue 传参了 id class 参数,但是子组件只接收了 class 参数。

vue
<template>
    <MyButton id="child" class="child" />
</template>

<script lang="ts" setup>
import MyButton from './MyButton.vue'
</script>
<template>
    <MyButton id="child" class="child" />
</template>

<script lang="ts" setup>
import MyButton from './MyButton.vue'
</script>
vue
<template>
    <button>MyButton</button>
</template>

<script>
import { PropType } from 'vue'

const props = defineProps({
    class: {
        type: String,
        default: ''
    }
})
</script>
<template>
    <button>MyButton</button>
</template>

<script>
import { PropType } from 'vue'

const props = defineProps({
    class: {
        type: String,
        default: ''
    }
})
</script>

所以 id 就属于透传 Attributes,最终被渲染到 button 元素上。

html
<button id="child">MyButton</button>
<button id="child">MyButton</button>

深层组件继承

修改一下上方的例子,例如 MyButton 组件又调用了 MyButtonChild 组件的情况。

vue
<template>
    <MyButtonChild />
</template>

<script lang="ts" setup>
import MyButtonChild from './MyButtonChild.vue'
</script>
<template>
    <MyButtonChild />
</template>

<script lang="ts" setup>
import MyButtonChild from './MyButtonChild.vue'
</script>

MyButton 组件没有通过 props emits 去接收父组件传进来的属性,所以会继续透传给子组件 MyButtonChild,以此类推。

如果只接收了一部分属性,那么未被接收的也会继续透传给子组件。

多个根节点 Attributes 继承

继续使用上面的例子,如果 MyButton.vue 的模板中有多个根节点,就需要通过 $attrs 来手动继承 Attributes。否则将会抛出一个警告。

vue
<template>
    <button>MyButton</button>
    <button v-bind="$attrs">MyButton2</button>
</template>
<template>
    <button>MyButton</button>
    <button v-bind="$attrs">MyButton2</button>
</template>