提问人:Bambi Bunny 提问时间:8/16/2021 最后编辑:Bambi Bunny 更新时间:10/19/2023 访问量:82087
Vue 3 传递数组警告:无关的非 props 属性被传递给组件,但无法自动继承
Vue 3 passing array warning: Extraneous non-props attributes were passed to component but could not be automatically inherited
问:
拜托,我正在学习 VueJS 3,我可能遇到了更开始的问题。我在浏览器开发人员控制台中警告过,如下所示:
消息是:
[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.
我正在将对象数组传递给子组件。在我的父母的文章中,我有这样的实现:views/Home.vue
<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>
在儿童创作中,我有以下代码:components/ItemProperties.vue
<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>
我有没有功能并不重要。我是否有条件也没关系。如果我在数组中有循环,我会收到此警告default()
v-if
数据在文件中。文件部分在这里:data.js
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: '' },
],
},
]
PS:应用程序有效,但我害怕那个警告。我能做些什么,请喜欢正确的方式?
我很乐意提供任何建议。谢谢。
答:
该组件具有多个根节点,因为它在根中呈现一个带有 的列表。ItemProperties
v-for
根据类名 (),我认为您希望将该类应用于容器元素,因此一个简单的解决方案是将该元素(例如,a )添加到组件的根目录中:infobox-item-properties
div
// ItemProperties.vue
<template>
<div>
<section v-for="(item, index) in items" :key="index" class="box">
...
</section>
</div>
</template>
评论
好吧,我认为错误消息非常清楚。
您的组件正在渲染片段 - 因为它使用 .这意味着没有单个根元素。ItemProperties.vue
<div>
v-for
同时,您将 a 传递给组件 - 只能放置在 HTML 元素上。如果你把它放在 Vue 组件上,Vue 会尝试把它放在组件渲染的内容的根元素上。但是因为你的组件渲染的内容没有根元素,所以 Vue 不知道该放在哪里......class
<ItemProperties class="infobox-item-properties"
class
若要删除警告,请删除 或将 的内容包装到单个 .class="infobox-item-properties"
ItemProperties
<div>
上面描述的机制称为 Fallthrough Attributes(“Non-prop attributes”,Vue 2 文档)。很高兴知道这种自动继承可以关闭,这允许您自己将这些属性应用于除根元素之外您选择的元素(或组件)(这样做还可以消除错误消息)。
这可能非常有用。最值得注意的是,在围绕标准 HTML 元素(如输入或按钮)或某些库组件设计专门的包装器时,您可以告诉“这是一个按钮 - 您可以放置标准接受的任何内容,并且它会起作用”,而无需将所有标准属性重新定义为包装器的道具<button>
<button>
评论
您还可以通过执行以下操作来防止在子组件中传递属性:
export default defineComponent({
name: "ChildComponentName",
inheritAttrs: false // This..
})
来源:https://vuejs.org/guide/components/attrs.html
您正在将属性传递给它,但未声明它。class
ItemProperties
在选项 api 中声明应该可以解决这个问题。class
props
ItemProperties.vue (英语)
...
export default {
props:["class"],
...
}
这也可以从其路由定义中的父组件触发。确保只在实际需要的组件中添加它,并有一些路由参数作为道具。props: true
props: true
评论
thing/:thing_id/foo/:foo_id
:foo_id
:thing_id
Michael 的回答是正确的,但许多人仍然会陷入这个错误,因为它是由文档未涵盖或不太直观的一些额外场景(边缘情况)触发的。
问题 回顾一下,触发错误是因为我们正在传递一个属性(例如禁用),并且我们计划渲染的 vue 组件在其根目录中有 2 个或更多元素。(迈克尔对此有很好的解释)。
边缘情况:
- 如果您有 if/else 语句,也会触发此错误
- 如果根元素旁边有注释,也会触发此错误
- 如果使用传送或过渡,则根元素是实际使用的 HTML 元素(因此,如果传送或过渡块中有 2 个元素,则将触发此错误)。
我在这里详细介绍了这个错误: https://zelig880.com/how-to-solve-extraneous-non-props-attributes-in-vue-js
您可以将 defineProps 添加到脚本设置代码中,以消除此警告:
const props = defineProps(['class'])
避免此警告的另一种方法是动态添加类,如下所示:
<my-awesome-component
ref="myComponentEl"
/>
...
myComponentEl.classList.add('awesome-class');
评论
:
@