javascript - Hvordan omgå 'Duplicate keys detected' i v-for-løkke i Vue.Js?
Jeg har brukt Nuxt.Js i mitt siste prosjekt, og jeg brukte også Vuetify.js som UI-rammeverk, og språket er TypeScript. Jeg prøvde å lage dette bildet nedenfor ved å bruke følgende matriser.
export const dummyData = [
{
id: "1",
name: "a",
sub: [
{
id: "1#1",
name: "b",
sub_sub: [
{ id: "1#1#1", name: "b-a" },
{ id: "1#1#2", name: "b-b" },
]
},
{
id: "1#2",
name: "c",
sub_sub: [
{ id: "1#2#1", name: "c-a" },
]
},
]
},
{
id: "2",
name: "d",
sub: [
{
id: "2#1",
name: "e",
sub_sub: [
{ id: "1#2#1", name: "e-a" },
]
}
]
},
]
og jeg trodde jeg var ferdig med å lage datatabell ved å bruke følgende kode.
<template>
<div>
<v-simple-table dense>
<thead>
<tr>
<th class="blue lighten-5">name</th>
<th class="blue lighten-5">sub_name</th>
<th class="blue lighten-5">sub_sub_name</th>
</tr>
</thead>
<tbody>
<template v-for="item in items">
<template v-for="(subitem, iSub) in item.sub">
<tr v-for="(sub_subitem, iSub_sub) in subitem.sub_sub" :key="sub_subitem.id">
<td v-if="iSub === 0 & iSub_sub === 0" :rowspan="rowSpanCalc(item)">
{{ item.name }}
</td>
<td v-if="iSub_sub === 0" :rowspan="subitem.sub_sub.length">
{{ subitem.name }}
</td>
<td>{{ sub_subitem.name }}</td>
</tr>
</template>
</template>
</tbody>
</v-simple-table>
</div>
</template>
<script lang="ts">
import { Component, Vue } from 'nuxt-property-decorator'
import { dummyData } from '~/store/dummy'
@Component({})
export default class extends Vue {
items: any = []
created() {
this.items = dummyData
}
rowSpanCalc(item: any) {
const count = item.sub.reduce(
(total: any, curr: any) => total + curr.sub_sub.length,
0
)
console.log(count);
return count;
}
}
</script>
<style lang="scss" scoped>
table {
border-collapse: collapse !important;
}
.v-data-table--dense > .v-data-table__wrapper > table > tbody > tr > td {
border-bottom: thin solid rgba(0, 0, 0, 0.12) !important;
}
</style>
Jeg stilte spørsmål om disse problemene mine på StackOverflow. Og til slutt trodde jeg det var fullført!...... men etter noen dager spurte kunden min om en feil som nedenfor.
vue.runtime.esm.js?2b0e:619 [Vue warn]: Duplicate keys detected: '1#2#1'. This may cause an update error.
koden min ser ut til å ikke ha noen problemer. men den har noen problemer med v-bind:key. I template, vet jeg at taggen til "v-bind:key" ikke kan bruke dupliserte nøkler. Hvis jeg bruker noen "v-bind:key" i template, bruker jeg iterator for å skille hver "v-bind:key". Derfor brukte jeg én "v-bind:key", men feilen oppstod. Det er et veldig hodepineproblem for meg.
Hvordan kan jeg fikse feilen når jeg kjører denne koden? Kan noen gi meg råd?
Svar #1
nøkkelen må være unik. ha en nøkkel, kombinasjon av respektive indeks for alle 3 løkker
<template v -for="(item,item_index) in items">
<template v -for="(subitem, iSub) in item.sub">
<tr
v
-for="(sub_subitem, iSub_sub) in subitem.sub_sub"
:
key="`${item_index}-${iSub_sub}-${sub_subitem.id}`"
>
<td v -if="iSub === 0 & iSub_sub === 0" : rowspan="rowSpanCalc(item)">
{{ item.name }}
</td>
<td v -if="iSub_sub === 0" : rowspan="subitem.sub_sub.length">
{{ subitem.name }}
</td>
<td>{{ sub_subitem.name }}</td>
</tr>
</template>
</template>
Svar #2
Den gjør nøyaktig det den sier på boksen: [Vue warn]: Dupliserte nøkler oppdaget: '1#2#1'. Dette kan forårsake en oppdateringsfeil.
Dine data bruker "1#2#1" som en ID for flere elementer.
Hvis du korrigerer dataene dine slik at de har unike ID-er, vil feilen forsvinne, slik:
export const dummyData = [
{
id: "1",
name: "a",
sub: [
{
id: "1#1",
name: "b",
sub_sub: [
{ id: "1#1#1", name: "b-a" },
{ id: "1#1#2", name: "b-b" },
]
},
{
id: "1#2",
name: "c",
sub_sub: [
{ id: "1#2#1", name: "c-a" },
]
},
]
},
{
id: "2",
name: "d",
sub: [
{
id: "2#1",
name: "e",
sub_sub: [
// I changed "1#2#1" to "1#2#2"
{ id: "1#2#2", name: "e-a" },
]
}
]
},
]
