Esta página asume que usted ya ha leído Básicos de Componentes. Léalo primero si usted es nuevo con componentes.
Un atributo que no es prop es un atributo u escuchador de eventos que se pasa a un componente, pero no tiene una propiedad correspondiente definida en props o emits. Los ejemplos comunes de esto incluyen los atributos class
, style
e id
. Puede acceder estos atributos mediante la propiedad $attrs
.
Cuando un componente retorna un solo nodo raíz. los atributos que no son props serán automáticamente agregado a los atributos del nodo raíz. Por ejemplo, en la instancia de un componente date-picker:
app.component('date-picker', {
template: `
<div class="date-picker">
<input type="datetime-local" />
</div>
`
})
En el caso necesitamos definir el estado del componente date-picker mediante un atributo data-status
, será aplicado al nodo raíz (es decir, div.date-picker
).
<!-- el componente date-picker con un atributo que no es _prop_ -->
<date-picker data-status="activated"></date-picker>
<!-- el componente date-picker renderizado -->
<div class="date-picker" data-status="activated">
<input type="datetime-local" />
</div>
La misma regla se aplica a los escuchadores de eventos:
<date-picker @change="submitChange"></date-picker>
app.component('date-picker', {
created() {
console.log(this.$attrs) // { onChange: () => {} }
}
})
Este podría ser útil cuando tenemos un elemento HTML con un evento change
como el elemento raíz del componente date-picker
.
app.component('date-picker', {
template: `
<select>
<option value="1">Ayer</option>
<option value="2">Hoy</option>
<option value="3">Mañana</option>
</select>
`
})
En este caso, el escuchador del evento change
se pasa desde el componente padre al componente secundario y será disparado cuando se dispare el evento nativo change
del elemento <select>
. No necesitarémos emitir un evento desde el componente date-picker
explícamente:
<div id="date-picker" class="demo">
<date-picker @change="showChange"></date-picker>
</div>
const app = Vue.createApp({
methods: {
showChange(event) {
console.log(event.target.value) // registrará un valor de la opción seleccionada
}
}
})
Si no quiere que el componente herede automáticamente los atributos, puede establecer inheritAttrs: false
en las opciones del componente.
El escenario común para deshabilitar la herencia de un atributo es cuando los atributos necesitan aplicarse a los otros elementos al lado del nodo raíz.
A través de establecer la opción inheritAttrs
a false
, puede luego aplicar atributos al elemento eligido por usted mediante utilizar la propiedad $attrs
del componente, la cual incluye todos los atributos que no sean incluidos por las propiedades props
y emits
del componente (p. ej. class
, style
, escuchadores de v-on
, etc.).
Utilicemos nuestro componente date-picker desde la sección anterior, en el evento necesitamos aplicar todos los atributos que no son props al elemento input
en vez del elemento raíz div
, esto puede ser logrado mediante utilizar la abreviatura v-bind
.
app.component('date-picker', {
inheritAttrs: false,
template: `
<div class="date-picker">
<input type="datetime-local" v-bind="$attrs" />
</div>
`
})
Con esta nueva configuración, ¡nuestro atributo data-status
será aplicado a nuestro elemento input
!
<!-- el componente date-picker con un atributo que no es _prop_ -->
<date-picker data-status="activated"></date-picker>
<!-- el componente date-picker renderizado -->
<div class="date-picker">
<input type="datetime-local" data-status="activated" />
</div>
A diferencia de los componentes de un solo nodo raíz, los componentes con múltiples nodo raíces no poseen un comportamiento automático de fracaso de atributos (attribute fallthrough). Si $attrs
no es vinculado explícamente, una advertencia de tiempo de ejecución será emitido.
<custom-layout id="custom-layout" @click="changeValue"></custom-layout>
// Este emitirá una advertencia
app.component('custom-layout', {
template: `
<header>...</header>
<main>...</main>
<footer>...</footer>
`
})
// No advertencias, los atributos de $attrs se pasan al elemento <main>
app.component('custom-layout', {
template: `
<header>...</header>
<main v-bind="$attrs">...</main>
<footer>...</footer>
`
})