Reputation: 1655
For not having :key="item.id"
on <template>
, I'm getting this error:
But when I do put it on there as such:
<template v-for="item in Object.values(cart)" :key="item.id">
…then I get this error:
Here's the code in question:
<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>
How might I get around this circular-seeming issue?
Upvotes: 6
Views: 7392
Reputation: 1044
I recently got this error and was able to fix it by setting up Volar to use Vue 2.7 instead
// tsconfig.json
{
"compilerOptions": {
// ...
},
"vueCompilerOptions": {
"target": 2.7,
// "target": 2, // For Vue version <= 2.6.14
}
}
Upvotes: 1
Reputation: 161
Although it has been a year since this question, I recently encountered a similar problem in discussions with others and found the reason for the problem. I hope my answer can help other friends who see this answer.
The tag of the questioner is vue3. In vue3, the v-for standard syntax is used on the template tag to write the key on the template tag. Please see the official document here: https://v3.vuejs.org/guide/list.html#v-for-on-a-template.
as follows:
<template v-for="item in Object.values(cart)" :key="item.id">
I think the reason for the infinite loop error of the questioner is that the rules of vue2 and vue3 are used at the same time. My vue2 project uses the volar plugin also to cause this error. Use v-for on template tag, vue2 and vue3 use two kinds of rules.
vue2: vue/no-v-for-template-key vue3: vue/no-v-for-template-key-on-child
These two rules conflict with each other. Here is the official guidance document: https://eslint.vuejs.org/rules/no-v-for-template-key-on-child.html
I did not give a solution, because I am not clear about the other configuration of the questioner, but I think I have found the reason, and hope to help you troubleshoot the problem
Upvotes: 12
Reputation: 46
As explained by others, Vue.js will use the tag for rendering and compilation, it will not really exist in the DOM. The keys are required so that Vue's diffing algorhythm can tell the different instances of the components apart.
That said, after check your example I realized you do not need here, I assume your is inside a or tag, so you can simply v-for the itself.
Example:
<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>
I will take the chance to give you another tip I use on my own codes, instead of using record attributes, for example, 'item.id' I use the index generated by the looping that will always have a sequence avoiding duplicated errors and the most important, it will always have a valid value.
Example:
<tr v-for="(item, index) in Object.values(cart)" :key="`items_${index}`">
If it helps you, please, mark as answered.
Happy coding!
Upvotes: -1
Reputation: 1
Vue use template tag to know if is a component also like react you must return one element try this:
<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>
Upvotes: -1