如何消除 ESLint 错误 "<template v-for> key should be placed on the <template> tag"?

24

我在一个应用中使用NuxtJS和Vuetify。在使用v-data-table显示一张记录表格时,如果item.isActive为true,我希望显示一个徽章。为此,我正在<tr>内部循环遍历<template>。但是,每当我为<template>标签提供键时,我会得到'<template v-for>' cannot be keyed. Place the key on real elements instead的错误提示。当我尝试为<td>设置键时,我会得到<template v-for> key should be placed on the <template> tag.的错误提示。这种情况发生在VSCode中的ESLint。

第一个错误:

图片描述

第二个错误:

图片描述

实现:

  <v-data-table :items="items">
    <template v-slot:item="{ item }">
      <tr>
        <template v-for="(header, index) in headers">
          <td v-if="header.value === 'isActive'" :key="index">
            <v-badge bordered content="" offset-x="-10" color="'#64b54d'" />
          </td>
          <td
            v-else
            :key="index"
          >
            {{ item[header.value] }}
          </td>
        </template>
      </tr>
    </template>
  </v-data-table>

CodeSandbox链接:https://codesandbox.io/s/runtime-wood-q4mc5h?file=/pages/home.vue:11-585

提前致谢。


我添加了一个答案。你有机会看一下吗?希望它能符合你的期望。 - Rohìt Jíndal
3
这是您需要禁用的规则:https://eslint.vuejs.org/rules/no-v-for-template-key-on-child.html,即在package.json文件的eslintconfig>rules部分中添加"vue/no-v-for-template-key-on-child": "off"。但是,如果您的VS Code仍在抱怨,那可能是VueJS插件的原因 - 您可能需要与作者交流。 - ierdna
我可以问一下你为什么在这里使用 template 标签吗?为什么不把v-for放在你的 <tr>上? - miro
1
由于无法在同一元素上使用v-for和v-if,因此您需要修改代码。 - omatica
4个回答

9
我曾经遇到过类似的情况,对我来说,这就是问题的关键(尽管错误没有明确说明):
在那种情况下,没有理由使用<template>标签。在子元素内部放置v-for将会给出完全相同的输出。
以下是一些截图以澄清问题:
1. 这里有一个错误。 Here we have an error 2. 在子元素上添加v-if可能是使用<template>的原因之一(v-if不应该与v-for在同一元素上使用)。现在错误已经消失了。 No error anymore 3. 或者我们仅仅在<template>标签内循环元素,那么错误就消失了。 No error anymore

2

这个错误在DL标签中经常遇到。

模式A:内部元素上的关键字

  <dl>
    <template v-for="(faq, index) in props.faqData">
      <dt :key="`dt-${index}`">
        {{ faq.question }}
      </dt>
      <dd :key="`dd-${index}`">
        {{ faq.answer }}
      </dd>
    </template>
  </dl>

这在Vue3中表示:[plugin:vite:vue] <template v-for>的key应该放在<template>标签上。

模式B:在模板标签上使用Key

  <dl>
    <template v-for="(faq, index) in props.faqData" :key="`item-${index}`">
      <dt>
        {{ faq.question }}
      </dt>
      <dd>
        {{ faq.answer }}
      </dd>
    </template>
  </dl>

这会产生ESLint: '<template v-for>' cannot be keyed. Place the key on real elements instead.(vue/no-v-for-template-key)的警告。 但它似乎工作正常。

模式C:由div标签包装

  <dl>
    <div v-for="(faq, index) in props.faqData" :key="`dl-${index}`">
      <dt>
        {{ faq.question }}
      </dt>
      <dd>
        {{ faq.answer }}
      </dd>
    </div>
  </dl>

在这种情况下不会发生错误。但是,这个HTML是不正确的。

我的解决方案:抑制警告

  <dl>
    <!-- eslint-disable-next-line vue/no-v-for-template-key -->
    <template v-for="(faq, index) in props.faqData" :key="`item-${index}`">
      <dt>
        {{ faq.question }}
      </dt>
      <dd>
        {{ faq.answer }}
      </dd>
    </template>
  </dl>

只有在DL标签的情况下,我别无选择,只能抑制警告。


这也是我的解决方案,但不幸的是,这给我带来了编译错误。我使用的是Vue 2.7版本。 - Björn Andersson
1
这正是问题所在,我的解决方案是在dt和dd上放置一个v-if="true" - RiesvGeffen

0

在一个循环中,关键字不能用于两个节点。您必须像这样做

<v-data-table :items="items">
<template v-slot:item="{ item }">
  <tr>
    <template v-for="(header, index) in headers">
      <td key="index">
        <template v-if="header.value === 'isActive'">
          <v-badge bordered content="" offset-x="-10" color="'#64b54d'" />
        </template>

        <template v-else>
          {{ item[header.value] }}
        </template>
      </td>
    </template>
  </tr>
</template>

0

<template v-for> 不能被键控。请在实际元素上放置键。

您需要为模板中的所有元素设置键。如果除了<td>之外还有其他元素,则这些元素也需要具有唯一的键。考虑将这些元素移动到组件中。

可能的解决方案:

var vueStore = {
  state: {
            items: [
        {name: 'MacBook Air', price: 1000},
        {name: 'MacBook Pro', price: 1800},
        {name: 'Lenovo W530', price: 1400},
        {name: 'Acer Aspire One', price: 300}
      ]    
  }
}


var vm = new Vue({
  el: '#vue-instance',
  data: {
    vueState: vueStore.state
  }
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="vue-instance">
  <table class="table table-borderd table-striped">
    <tr>
      <template v-for="(item, index) in vueState.items">
        <td align="center" :key="index">{{ item.name }}</td>
      </template>
    </tr>
  </table>
</div>


谢谢您的回答。如果您不介意,能否添加一个例子? - user16583522
嗨,感谢您的更新。问题是我正在使用vuetify和启用了eslint默认规则的nuxtjs项目上工作。如果您不介意,可以尝试通过npx create-nuxt-app <app-name>命令并选择eslint进行代码检查,并在本地检查一下吗?我将不胜感激。 - user16583522
现在我无法做到,因为我正在优先处理其他项目。对此感到抱歉。 - Rohìt Jíndal
好的。没有问题。 - user16583522
4
问题出错了:在 <template> 标签上应该放置 <template v-for> 的 key。你的答案与他的问题相同。 - radzi0_0
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接