# Atributos Não-Propriedades

Esta página assume que você já leu o Básico sobre Componentes. Leia lá primeiro se você for novo em componentes.

Um atributo de componente não-propriedade é um atributo ou ouvinte de evento que é passado para um componente, mas não tem uma propriedade correspondente definida em props ou emits. Os exemplos comuns disto incluem atributos class, style, e id. Você pode acessar esses atributos por meio da propriedade $attrs.

# Herança de Atributos

Quando um componente retorna um único nó raiz, atributos não-propriedade serão automaticamente adicionados aos atributos do nó raiz. Por exemplo, na instância de um componente date-picker:

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

No caso de precisarmos definir o status do componente date-picker por meio de um atributo data-status, ele será aplicado ao nó raiz (ou seja, div.date-picker).

<!-- Componente date-picker com um atributo não-propriedade -->
<date-picker data-status="activated"></date-picker>

<!-- Componente date-picker renderizado -->
<div class="date-picker" data-status="activated">
  <input type="datetime-local" />
</div>
1
2
3
4
5
6
7

A mesma regra se aplica aos ouvintes de eventos:

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

Isso pode ser útil quando temos um elemento HTML com um evento change como elemento raiz de date-picker.

app.component('date-picker', {
  template: `
    <select>
      <option value="1">Ontem</option>
      <option value="2">Hoje</option>
      <option value="3">Amanhã</option>
    </select>
  `
})
1
2
3
4
5
6
7
8
9

Nesse caso, o evento change é passado do componente pai para o filho e será acionado no evento nativo change do <select>. Não precisamos emitir um evento de date-picker explicitamente:

<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) // exibirá o valor da opção selecionada
    }
  }
})
1
2
3
4
5
6
7

# Desativando a Herança de Atributos

Se você não deseja que um componente herde atributos automaticamente, você pode definir inheritAttrs: false nas opções do componente.

O cenário comum para desativar uma herança de atributo é quando os atributos precisam ser aplicados a outros elementos além do nó raiz.

Ao definir a opção inheritAttrs para false, você poderá aplicar atributos ao elemento de sua escolha usando a propriedade $attrs do componente, que inclui todos os atributos não incluídos às propriedades props e emits do componente (por exemplo, class, style, eventos v-on, etc.).

Usando nosso exemplo de componente date-picker da seção anterior, no caso de precisarmos aplicar todos os atributos não-propriedade ao elemento input ao invés do elemento div raiz, podemos fazer usando o atalho 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

Com esta nova configuração, nosso atributo data-status será aplicado ao nosso elemento input!

<!-- Componente date-picker com um atributo não-propriedade -->
<date-picker data-status="activated"></date-picker>

<!-- Componente date-picker renderizado -->
<div class="date-picker">
  <input type="datetime-local" data-status="activated" />
</div>
1
2
3
4
5
6
7

# Herança de Atributos em Vários Nós Raízes

Ao contrário dos componentes de um único nó raiz, os componentes com vários nós raízes não têm um comportamento de falha de atributo automático. Se $attrs não for vinculado explicitamente, um aviso de tempo de execução será emitido.

<custom-layout id="custom-layout" @click="changeValue"></custom-layout>
1
// Isso gerará um aviso
app.component('custom-layout', {
  template: `
    <header>...</header>
    <main>...</main>
    <footer>...</footer>
  `
})

// Sem avisos, $attrs são passados para o elemento <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