inheritAttrs и гибкая работа с компонентамиВнезапно, да? Но тем не менее, сегодня у нас
Vue 👆В нем есть такая штука, как атрибуты, которые бывают пропускаемыми и непропускаемыми. Разберёмся сегодня с этим.
📌Пропускаемые атрибуты — это те атрибуты, которые явно определены в виде пропсов компонента. Они предназначены для того, чтобы передавать данные от родительского компонента к дочернему. Например, если у вас есть компонент с пропсом
title, то любой атрибут title, переданный этому компоненту, будет считаться пропускаемым.📌Непропускаемые атрибуты, в свою очередь, — это любые атрибуты, которые не были определены в виде пропсов компонента. Эти атрибуты не используются самим компонентом, но по умолчанию
Vue передаёт их на корневой элемент компонента. Примером может служить атрибут class, если он не был определён как пропс.➡️Рассмотрим простой компонент
Content.vue, который не содержит никаких пропсов:
<template>
<div>
<h2>
<slot name="title">no title</slot>
</h2>
<p>
<slot name="description">no description</slot>
</p>
</div>
</template>
➡️Если мы используем этот компонент и передадим ему атрибуты, такие как
titleClass, descClass и wrapClass, они будут переданы на корневой элемент — div:
<Content
titleClass="title"
descClass="description"
wrapClass="wrap"
>
<template v-slot:title>Hello world!</template>
<template v-slot:description>Hello description!</template>
</Content>
➡️Отрендеренная разметка будет выглядеть следующим образом:
<div titleclass="title" descclass="description" wrapclass="wrap">
<h2>Hello world!</h2>
<p>Hello description!</p>
</div>
➡️Это ожидаемое поведение, поскольку Vue по умолчанию передает непропускаемые атрибуты на корневой элемент компонента. Однако, если мы захотим изменить это поведение, мы можем воспользоваться опцией
inheritAttrs.Мы добавим следующую настройку в наш компонент:
<script setup>
defineOptions({
inheritAttrs: false,
});
</script>
<template>
<div :class="$attrs.wrapClass">
<h2 :class="$attrs.titleClass">
<slot name="title">no title</slot>
</h2>
<p :class="$attrs.descClass">
<slot name="description">no description</slot>
</p>
</div>
</template>
➡️Теперь непропускаемые атрибуты не будут передаваться на корневой элемент, вместо этого они будут доступны через объект
$attrs. Разметка после рендера изменится:
<div class="wrap">
<h2 class="title">Hello world!</h2>
<p class="description">Hello description!</p>
</div>
Как мы видим, с помощью этой опции можно значительно упростить работу в определённых ситуациях и настроить компоненты более гибко.
#vue