Vue 3 传递数组警告:无关的非 props 属性被传递给组件,但无法自动继承

Vue 3 passing array warning: Extraneous non-props attributes were passed to component but could not be automatically inherited

提问人:Bambi Bunny 提问时间:8/16/2021 最后编辑:Bambi Bunny 更新时间:10/19/2023 访问量:82087

问:

拜托,我正在学习 VueJS 3,我可能遇到了更开始的问题。我在浏览器开发人员控制台中警告过,如下所示:

enter image description here

消息是:

[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:应用程序有效,但我害怕那个警告。我能做些什么,请喜欢正确的方式?

我很乐意提供任何建议。谢谢。

javascript 数组 vue.js 警告 vuejs3

评论

0赞 Anna Madsen 2/22/2023
不是对您的案例的答案,而是对另一种案例中相同错误消息的答案。在这里,我在父组件中使用了 a 而不是 a 进行事件处理:@

答:

14赞 tony19 8/16/2021 #1

该组件具有多个根节点,因为它在根中呈现一个带有 的列表。ItemPropertiesv-for

根据类名 (),我认为您希望将该类应用于容器元素,因此一个简单的解决方案是将该元素(例如,a )添加到组件的根目录中:infobox-item-propertiesdiv

// ItemProperties.vue
<template>
  <div>
    <section v-for="(item, index) in items" :key="index" class="box">
    ...
    </section>
  </div>
</template>

演示

评论

0赞 Samuel Nonoka 9/1/2023
这对我有用
105赞 Michal Levý 8/16/2021 #2

好吧,我认为错误消息非常清楚。

您的组件正在渲染片段 - 因为它使用 .这意味着没有单个根元素。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>

评论

0赞 Dylan Wright 12/16/2022
继承是编程的一个基本功能。所以我明白了,但发现这是一个神奇的功能。这就是导致错误的原因,默认情况下打开继承。让我们让一切都失败,看似强大但危险
0赞 tcrite 4/2/2023
这是 v2 中允许的,但 v3 中不允许的吗?直到从 v2 迁移到 v3,我才开始收到此错误。
1赞 Michal Levý 4/3/2023
@tcrite 在 Vue 2 中甚至不可能描述这种情况,因为在 Vue 2 中有一个规则,即组件必须渲染单个根元素。所以这实际上是一个新问题,因为 Vue 3 允许渲染多个根元素(所谓的片段)
1赞 hitautodestruct 5/18/2023
您也可以使用来解决这种情况。vuejs.org/guide/components/......v-bind="$attrs"
10赞 Per 2/21/2022 #3

您还可以通过执行以下操作来防止在子组件中传递属性:

export default defineComponent({
  name: "ChildComponentName",
  inheritAttrs: false // This..
})

来源:https://vuejs.org/guide/components/attrs.html

0赞 fsarter 7/21/2022 #4

您正在将属性传递给它,但未声明它classItemProperties

在选项 api 中声明应该可以解决这个问题。classprops

ItemProperties.vue (英语)

...
export default {
  props:["class"],
  ...
}
2赞 infinity 8/11/2022 #5

这也可以从其路由定义中的父组件触发。确保只在实际需要的组件中添加它,并有一些路由参数作为道具。props: trueprops: true

评论

0赞 chipit24 11/29/2022
这是我的情况中的问题,尽管道具是从父路由配置传递下来的,即 ),我的路由只需要,但即使我不需要它,我也必须指定。thing/:thing_id/foo/:foo_id:foo_id:thing_id
0赞 Jack 12/10/2022
是的,对我来说同样的问题,当将一个参数从父路由传递到嵌套路由时,我必须声明父路由组件中未使用的参数以避免这种警告
3赞 Zelig880 5/9/2023 #6

Michael 的回答是正确的,但许多人仍然会陷入这个错误,因为它是由文档未涵盖或不太直观的一些额外场景(边缘情况)触发的。

问题 回顾一下,触发错误是因为我们正在传递一个属性(例如禁用),并且我们计划渲染的 vue 组件在其根目录中有 2 个或更多元素。(迈克尔对此有很好的解释)。

边缘情况:

  • 如果您有 if/else 语句,也会触发此错误
  • 如果根元素旁边有注释,也会触发此错误
  • 如果使用传送或过渡,则根元素是实际使用的 HTML 元素(因此,如果传送或过渡块中有 2 个元素,则将触发此错误)。

我在这里详细介绍了这个错误: https://zelig880.com/how-to-solve-extraneous-non-props-attributes-in-vue-js

0赞 shasi kanth 8/29/2023 #7

您可以将 defineProps 添加到脚本设置代码中,以消除此警告:

const props = defineProps(['class'])
0赞 V. Sambor 10/19/2023 #8

避免此警告的另一种方法是动态添加类,如下所示:

<my-awesome-component 
    ref="myComponentEl"
/>

...

myComponentEl.classList.add('awesome-class');