por favor, estoy aprendiendo un VueJS 3 y probablemente tenga un problema de principiante. Tengo una advertencia en la consola del desarrollador del navegador como esta:
El mensaje es:
[Vue warn]: Extraneous non-props attributes (class) were passed to component but could not be automatically inherited because component renders fragment or text root nodes.
Estoy pasando una matriz de objetos al Componente secundario. En mi componente principal views/Home.vue
tengo esta implementación:
<template> <div class="wrapper"> <section v-for="(item, index) in items" :key="index" class="box"> <ItemProperties class="infobox-item-properties" :info="item.properties" /> </section> </div> </template> <script> import { ref } from 'vue' import { data } from '@/data.js' import ItemProperties from '@/components/ItemProperties.vue' export default { components: { ItemDescription, }, setup() { const items = ref(data) return { items, } }, </script>
En child compoment components/ItemProperties.vue
tengo este código:
<template> <div class="infobox-item-property" v-for="(object, index) in info" :key="index"> <span class="infobox-item-title">{{ object.name }}:</span> <span v-if="object.type === 'rating'"> <span v-for="(v, k) in object.value" :key="k">{{ object.icon }}</span> </span> <span v-else> <span>{{ object.value }}</span> </span> </div> </template> <script> export default { props: { info: { type: Array, required: false, default: () => [ { name: '', value: '', type: 'string', icon: '', }, ], }, }, } </script>
No importa si tengo la función default()
o no. Tampoco importa si tengo la condición v-if
o no. Si tengo ciclo en el Array, tengo esta advertencia
Los datos están en el archivo data.js
La parte del archivo está aquí:
export const data = [ { title: 'White shirt', properties: [ { name: 'Material', value: 'Cotton', type: 'string', icon: '' }, { name: 'Size', value: 'M', type: 'string', icon: '' }, { name: 'Count', value: 4, type: 'number', icon: '' }, { name: 'Absorption', value: 4, type: 'rating', icon: '💧' }, { name: 'Rating', value: 2, type: 'rating', icon: '⭐️' }, { name: 'Confort', value: 2, type: 'rating', icon: '🛏' }, { name: 'Sleeves', value: 'Short', type: 'string', icon: '' }, { name: 'Color', value: 'White', type: 'string', icon: '' }, ], }, ]
PD: La aplicación funciona, pero me temo que esa advertencia. ¿Qué puedo hacer por favor como la manera correcta?
Estaré encantado de cualquier consejo. Muchas gracias.
El componente ItemProperties
tiene varios nodos raíz porque representa una lista en la raíz con v-for
.
Según el nombre de la clase ( infobox-item-properties
), creo que desea que la clase se aplique a un elemento contenedor, por lo que una solución simple es simplemente agregar ese elemento (por ejemplo, un div
) en su componente en la raíz:
// ItemProperties.vue <template> <div> <section v-for="(item, index) in items" :key="index" class="box"> ... </section> </div> </template>
Bueno, creo que el mensaje de error es bastante claro.
Su componente ItemProperties.vue
está representando fragmentos , porque está representando múltiples elementos <div>
usando v-for
. Lo que significa que no hay un único elemento raíz .
Al mismo tiempo, está pasando una class
al componente con <ItemProperties class="infobox-item-properties"
- class
solo se puede colocar en elementos HTML. Si lo coloca en el componente Vue, Vue intenta colocarlo en el elemento raíz del contenido que está representando el componente. Pero debido a que el contenido que representa su componente no tiene un elemento raíz, Vue no sabe dónde colocarlo...
Para eliminar la advertencia, elimine class="infobox-item-properties"
o ajuste el contenido de ItemProperties
a un solo <div>
.
El mecanismo descrito anteriormente se llama Fallthrough Attributes ("Atributos no prop" Vue 2 docs). Es bueno saber que esta herencia automática se puede desactivar, lo que le permite aplicar esos atributos usted mismo en el elemento (o componente) que elija además del elemento raíz. Esto puede ser muy útil. Más notablemente cuando se diseñan envoltorios especializados alrededor de elementos HTML estándar (como entrada o botón) o algún componente de biblioteca...
También podría evitar pasar atributos en componentes secundarios haciendo esto:
export default defineComponent({ name: "ChildComponentName", inheritAttrs: false // This.. })