Ошибка при запросе: ключ должен быть помещен в <шаблон>
За отсутствие :key="item.id"
на <template>
, Я получаю эту ошибку:
Но когда я все же помещаю его туда как таковой:
<template v-for="item in Object.values(cart)" :key="item.id">
… Тогда я получаю эту ошибку:
Вот рассматриваемый код:
<template v-for="item in Object.values(cart)">
<tr :key="item.id">
<td>Digest {{ item.digestId }}</td>
<td>{{ item.duration_text }} subscription</td>
<td class="price-cell">${{ roundMoney(item.price, 2) }}</td>
<td class="trash-cell">
<fa-icon icon="times-circle" size="lg" @click="removeItem(item)" />
</td>
</tr>
<tr v-if="item.discounts.length" :key="`${item.id}-${item.discounts && item.discounts[0].id}`">
<td colspan="2">
<label>Code: {{ item.discounts[0].code }}</label>
</td>
<td colspan="2">
<span class="discount-amount">–${{ item.discounts[0].percent_off }}</span>
</td>
<td class="trash-discount-cell">
<fa-icon icon="times-circle" class="trash" @click="rmDscnt(item.discounts[0])" />
</td>
</tr>
</template>
Как я могу обойти эту кажущуюся круговой проблему?
5 ответов
Хотя с этого вопроса прошел год, недавно я столкнулся с подобной проблемой в обсуждениях с другими и нашел причину проблемы. Я надеюсь, что мой ответ поможет другим друзьям, которые увидят этот ответ.
Тег спрашивающего — vue3. В vue3 стандартный синтаксис v-for используется в теге шаблона для записи ключа в теге шаблона. См. официальный документ здесь: https://v3.vuejs.org/guide/list.html#v-for-on-a-template.
следующим образом:
<template v-for="item in Object.values(cart)" :key="item.id">
Я думаю, что причина ошибки бесконечного цикла вопрошающего заключается в том, что правила vue2 и vue3 используются одновременно. Мой проект vue2 также использует плагин volar, чтобы вызвать эту ошибку. Используйте v-for в теге шаблона, vue2 и vue3 используют два типа правил.
vue2: vue/no-v-for-template-keyvue3: vue/no-v-for-template-key-on-child
Эти два правила противоречат друг другу. Вот официальный руководящий документ: https://eslint.vuejs.org/rules/no-v-for-template-key-on-child.html .
Я не дал решения, потому что мне непонятна другая конфигурация вопрошающего, но я думаю, что нашел причину, и надеюсь помочь вам решить проблему.
Недавно я получил эту ошибку и смог ее исправить, настроив Volar на использование Vue 2.7.
// tsconfig.json
{
"compilerOptions": {
// ...
},
"vueCompilerOptions": {
"target": 2.7,
// "target": 2, // For Vue version <= 2.6.14
}
}
Как объяснили другие, Vue.js будет использовать тег для рендеринга и компиляции, на самом деле он не будет существовать в DOM. Ключи необходимы, чтобы алгоритм различения Vue мог различать разные экземпляры компонентов.
Тем не менее, после проверки вашего примера я понял, что вам здесь не нужно, я предполагаю, что вы находитесь внутри тега или, поэтому вы можете просто v-для самого себя.
Пример:
<table>
<tbody>
<tr v-for="item in Object.values(cart)" :key="item.id">
<td>Digest {{ item.digestId }}</td>
<td>{{ item.duration_text }} subscription</td>
<td class="price-cell">${{ roundMoney(item.price, 2) }}</td>
<td class="trash-cell">
<fa-icon icon="times-circle" size="lg" @click="removeItem(item)" />
</td>
</tr>
<tr v-if="item.discounts.length" :key="`${item.id}-${item.discounts && item.discounts[0].id}`">
<td colspan="2">
<label>Code: {{ item.discounts[0].code }}</label>
</td>
<td colspan="2">
<span class="discount-amount">–${{ item.discounts[0].percent_off }}</span>
</td>
<td class="trash-discount-cell">
<fa-icon icon="times-circle" class="trash" @click="rmDscnt(item.discounts[0])" />
</td>
</tr>
</tbody>
</table>
Я воспользуюсь возможностью дать вам еще один совет, который я использую в своих собственных кодах, вместо использования атрибутов записи, например, 'item.id', я использую индекс, сгенерированный циклом, который всегда будет иметь последовательность, избегающую повторяющихся ошибок и самое главное, он всегда будет иметь действительное значение.
Пример:
<tr v-for="(item, index) in Object.values(cart)" :key="`items_${index}`">
Если это вам поможет, отметьте ответ.
Удачного кодирования!
В Vue.js <template>
не может быть задействован, потому что он используется vue для рендеринга и компиляции компонентов.
Попробуйте использовать другие элементы, такие как div, разделы и другие.
Vue использует тег шаблона, чтобы узнать, является ли компонент компонентом, как и реагировать, вы должны вернуть один элемент, попробуйте это:
<template>
<div>
<section v-for="item in Object.values(cart)">
<tr :key="item.id">
<td>Digest {{ item.digestId }}</td>
<td>{{ item.duration_text }} subscription</td>
<td class="price-cell">${{ roundMoney(item.price, 2) }}</td>
<td class="trash-cell">
<fa-icon icon="times-circle" size="lg" @click="removeItem(item)" />
</td>
</tr>
<tr v-if="item.discounts.length" :key="`${item.id}-${item.discounts && item.discounts[0].id}`">
<td colspan="2">
<label>Code: {{ item.discounts[0].code }}</label>
</td>
<td colspan="2">
<span class="discount-amount">–${{ item.discounts[0].percent_off }}</span>
</td>
<td class="trash-discount-cell">
<fa-icon icon="times-circle" class="trash" @click="rmDscnt(item.discounts[0])" />
</td>
</tr>
</section>
</div>
</template>