# Передача обычных атрибутов

Подразумевается, что вы уже изучили и разобрались с разделом Основы компонентов. Если нет — прочитайте его сначала.

Обычный атрибут для компонента — атрибут или слушатель события, который передаётся в компонент, но не имеет соответствующего свойства в props или emits. Частыми примерами подобного являются атрибуты class, style и id. Получить доступ к этим атрибутам можно через свойство $attrs.

# Наследование атрибутов

Обычные атрибуты будут добавлены к атрибутам корневого элемента автоматически, когда компонент возвращает один корневой элемент. Например, для компонента выбора даты:

app.component('date-picker', {
  template: `
    <div class="date-picker">
      <input type="datetime-local" />
    </div>
  `
})
1
2
3
4
5
6
7

В случае когда требуется устанавливать статус компонента выбора даты через свойство data-status, значение будет добавлено к корневой ноде (т.е., div.date-picker).

<!-- Компонент выбора даты с передачей обычного атрибута -->
<date-picker data-status="activated"></date-picker>

<!-- Отрисованный компонент выбора даты -->
<div class="date-picker" data-status="activated">
  <input type="datetime-local" />
</div>
1
2
3
4
5
6
7

Это же правило применяется и для прослушивания событий:

<date-picker @change="submitChange"></date-picker>
1
app.component('date-picker', {
  created() {
    console.log(this.$attrs) // { onChange: () => {}  }
  }
})
1
2
3
4
5

Подобное удобно, когда в качестве корневого элемента компонента date-picker будет HTML-элемент, генерирующий событие change .

app.component('date-picker', {
  template: `
    <select>
      <option value="1">Вчера</option>
      <option value="2">Сегодня</option>
      <option value="3">Завтра</option>
    </select>
  `
})
1
2
3
4
5
6
7
8
9

Обработчик события change будет передан из родительского компонента в дочерний и станет вызываться при нативном событии change на корневом элементе <select>. В таком случае не потребуется явно генерировать событие из date-picker:

<div id="date-picker" class="demo">
  <date-picker @change="showChange"></date-picker>
</div>
1
2
3
const app = Vue.createApp({
  methods: {
    showChange(event) {
      console.log(event.target.value) // отобразит значение выбранного варианта
    }
  }
})
1
2
3
4
5
6
7

# Отключение наследования атрибутов

Если необходимо отключить автоматическое наследование атрибутов компонентом, то это можно сделав с помощью опции inheritAttrs: false.

Популярный сценарий, когда требуется отключать наследование атрибутов — необходимо добавлять атрибуты на другие элементы вместо корневого узла.

Устанавливая опцию inheritAttrs в значение false, можно контролировать добавление атрибутов к другим элементам компонента через свойство $attrs, которое включает в себя все атрибуты, не входящие в состав свойств props и emits (например, class, style, обработчики v-on, и т.д.).

Используя пример компонента для выбора дат из предыдущей главы, сделаем добавление обычных атрибутов на элемент input, вместо корневого элемента div. Воспользуемся для этого сокращённой записью v-bind:





 




app.component('date-picker', {
  inheritAttrs: false,
  template: `
    <div class="date-picker">
      <input type="datetime-local" v-bind="$attrs" />
    </div>
  `
})
1
2
3
4
5
6
7
8

С такими настройками атрибут data-status будет добавляться на элемент input!

<!-- Компонент выбора даты с передачей обычного атрибута -->
<date-picker data-status="activated"></date-picker>

<!-- Отрисованный компонент выбора даты -->
<div class="date-picker">
  <input type="datetime-local" data-status="activated" />
</div>
1
2
3
4
5
6
7

# Наследование атрибутов при нескольких корневых элементах

В отличие от компонентов с одним корневым элементом, компоненты с несколькими корневыми элементами не имеют автоматического наследования атрибутов. Если $attrs не были привязаны явно — будет выдано предупреждение во время выполнения кода.

<custom-layout id="custom-layout" @click="changeValue"></custom-layout>
1
// Это вызовет предупреждение
app.component('custom-layout', {
  template: `
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  `
})

// Всё ок, $attrs передаются на элемент <main>
app.component('custom-layout', {
  template: `
    <header>...</header>
    <main v-bind="$attrs">...</main>
    <footer>...</footer>
  `
})
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17

Deployed on Netlify.
Последнее обновление: 2021-02-25, 10:16:09 UTC