drunkdolphin
drunkdolphin

Reputation: 797

How to escape 'Duplicate keys detected' in v-for loop at Vue.Js?

I have used Nuxt.Js in my latest project and I also used Vuetify.js as UI framework, and language is TypeScript. I tried to make this image below using following arrays.

my output

    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" },
                ]
            }
        ]
    },
]

and I thought I finished to make data table using following code.

    <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>

I asked question about these my issues in stackoverflow. and finally I thought it was completed!...... but after few days, my customer asked some error like below.

vue.runtime.esm.js?2b0e:619 [Vue warn]: Duplicate keys detected: '1#2#1'. This may cause an update error.

my code seems like no problem. but it has some problem about v-bind:key. In template, I know tag of "v-bind:key" can't use duplicate key. If I use some "v-bind:key" in template, I use iterator to distinguish each "v-bind:key". That's why I used one "v-bind:key" , but error occurred. It ’s a very headache problem for me.

How can I fix the error when I run this code? Could anyone advise me?

Upvotes: 3

Views: 2386

Answers (2)

Nilesh Patel
Nilesh Patel

Reputation: 3317

key must be unique. have a key, combination of respective index of all 3 loop

<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>

Upvotes: 2

Justin Taddei
Justin Taddei

Reputation: 2276

It's doing exactly what it says on the tin: [Vue warn]: Duplicate keys detected: '1#2#1'. This may cause an update error.

Your data uses "1#2#1" as an id for multiple items.

If you correct your data to have unique id's the error will go away, like so:

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" },
                ]
            }
        ]
    },
]

Upvotes: 1

Related Questions