Прохідні атрибути
Ця сторінка передбачає, що ви вже прочитали основи компонентів. Прочитайте це спочатку, якщо ви новачок у компонентах.
Наслідування атрибутів
Прохідний атрибут — це атрибут або v-on
слухач подій, який передається компоненту, але не оголошується явно в реквізитах або випромінюваннях приймаючого компонента. Типовими прикладами цього є атрибути class
, style
та id
.
Коли компонент рендерить один кореневий елемент, прохідні атрибути будуть автоматично додані до атрибутів кореневого елемента. Наприклад, задано компонент <MyButton>
з таким шаблоном:
template
<!-- шаблон <MyButton> -->
<button>натисніть мене</button>
І батько, який використовує цей компонент:
template
<MyButton class="large" />
Кінцевий відрендерений DOM буде таким:
html
<button class="large">натисніть мене</button>
Тут <MyButton>
не оголосив class
як прийнятний реквізит. Таким чином, class
розглядається як прохідний атрибут і автоматично додається до кореневого елемента <MyButton>
.
Злиття class
та style
Якщо кореневий елемент дочірнього компонента вже має наявні атрибути class
або style
, його буде об’єднано зі значеннями class
і style
, успадкованими від батьківського. Наприклад, ми змінили шаблон <MyButton>
у попередньому прикладі на:
template
<!-- шаблон <MyButton> -->
<button class="btn">натисніть мене</button>
Кінцевий відрендерений DOM буде таким:
html
<button class="btn large">натисніть мене</button>
Наслідування слухача v-on
Те саме правило застосовується до слухачів подій v-on
:
template
<MyButton @click="onClick" />
Слухач click
буде додано до кореневого елемента <MyButton>
, тобто власного елемента <button>
. Натискання саме <button>
запустить метод onClick
батьківського компонента. Якщо власний елемент <button>
вже має click
слухач, пов'язаний з v-on
, тоді обидва слухачі будуть активовані.
Вкладене наслідування компонентів
Наприклад, якщо компонент відображає інший компонент як свій кореневий, ми переробили <MyButton>
, щоб відобразити <BaseButton>
як його кореневий вузол:
template
<!-- шаблон <MyButton/> який просто відображає інший компонент -->
<BaseButton />
Тоді прохідні атрибути, отримані <MyButton>
, будуть автоматично перенаправлені <BaseButton>
.
Зауважте:
Перенаправлені атрибути не включають жодних атрибутів, оголошених як реквізити, або
v-on
слухачів оголошених подій<MyButton>
— іншими словами, оголошені атрибути та слухачі були "спожиті"<MyButton>
.Перенаправлені атрибути можуть бути прийняті як реквізити
<BaseButton>
, якщо вони оголошені ним.
Вимкнення наслідування атрибутів
Якщо ви не хочете, щоб компонент автоматично наслідував атрибути, ви можете встановити inheritAttrs: false
у параметрах компонента.
Починаючи з 3.3 ви також можете використовувати defineOptions
безпосередньо в <script setup>
:
vue
<script setup>
defineOptions({
inheritAttrs: false
})
// ...логіка налаштування
</script>
Загальний сценарій вимкнення наслідування атрибутів полягає в тому, що атрибути потрібно застосувати до інших елементів, крім кореневого вузла. Установивши для параметра inheritAttrs
значення false
, ви можете отримати повний контроль над тим, де слід застосовувати прохідні атрибути.
Ці прохідні атрибути можна отримати безпосередньо у виразах шаблону як $attrs
:
template
<span>Прохідні атрибути: {{ $attrs }}</span>
Об’єкт $attrs
включає всі атрибути, які не оголошені параметрами props
або emits
компонента (наприклад, class
, style
, v-on
слухачі тощо).
Деякі примітки:
На відміну від реквізитів, прохідні атрибути зберігають свій початковий регістр у JavaScript, тому до такого атрибута, як
foo-bar
, потрібно звертатися як$attrs['foo-bar']
.Слухач подій
v-on
, як@click
, буде представлений в об’єкті як функція в$attrs.onClick
.
Використовуючи наш приклад компонента <MyButton>
з попереднього розділу – іноді нам може знадобитися обернути фактичний елемент <button>
додатковим <div>
для стилізації:
template
<div class="btn-wrapper">
<button class="btn">натисніть мене</button>
</div>
Ми хочемо, щоб усі прохідні атрибути, такі як class
і v-on
слухачі, застосовувалися до внутрішнього <button>
, а не до зовнішнього <div>
. Ми можемо досягти цього за допомогою inheritAttrs: false
та v-bind="$attrs"
:
template
<div class="btn-wrapper">
<button class="btn" v-bind="$attrs">натисніть мене</button>
</div>
Пам’ятайте, що v-bind
без аргументу прив’язує всі властивості об’єкта як атрибути цільового елемента.
Наслідування атрибутів на кількох кореневих вузлах
На відміну від компонентів з одним кореневим вузлом, компоненти з кількома кореневими вузлами не мають автоматичної поведінки проходу атрибутів. Якщо $attrs
не прив'язані явно, буде видано попередження під час виконання.
template
<CustomLayout id="custom-layout" @click="changeValue" />
Якщо <CustomLayout>
має наступний багатокореневий шаблон, виникне попередження, оскільки Vue не може бути впевнений, де застосувати прохідні атрибути:
template
<header>...</header>
<main>...</main>
<footer>...</footer>
Попередження зникне, якщо $attrs
прив'язано явно:
template
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
Доступ до прохідних атрибутів in JavaScript
За потреби ви можете отримати доступ до прохідних атрибутів в <script setup>
за допомогою API useAttrs()
:
vue
<script setup>
import { useAttrs } from 'vue'
const attrs = useAttrs()
</script>
Без використання <script setup>
, attrs
буде представлено як властивість контексту setup()
:
js
export default {
setup(props, ctx) {
// прохідні атрибути представлені як ctx.attrs
console.log(ctx.attrs)
}
}
Зауважте, що хоча об’єкт attrs
тут завжди відображає останні прохідні атрибути, він не є реактивним (з причин продуктивності). Ви не можете використовувати спостерігачі для спостереження за його змінами. Якщо вам потрібна реактивність, використовуйте реквізити. Крім того, ви можете використовувати onUpdated()
, щоб виконувати побічні ефекти з останніми attrs
під час кожного оновлення.