首页 > 解决方案 > 如何为我的 v-for 循环设置有效的原始密钥?

问题描述

我需要在数据表中显示一个 v 对话框,该对话框基本上包含一个餐厅菜单,该菜单结构为对象数组的对象数组。这就是我已经构建菜单的方式:

menu_ristorante: [
      {
        primi: [
          { nome_portata: "Fettuccine al ragù", quantita_portata: 0 },
          { nome_portata: "Tagliatelle alla boscaiola", quantita_portata: 0 },
          { nome_portata: "Spaghetti allo scoglio", quantita_portata: 0 },
          { nome_portata: "Zuppa di ceci", quantita_portata: 0 },
          { nome_portata: "Fettuccine al ragù", quantita_portata: 0 }
        ]
      },
      {
        secondi: [{ nome_portata: "Vitello tonnato", quantita_portata: 0 }]
      },
      {
        contorni: [{ nome_portata: "Insalata mista", quantita_portata: 0 }]
      },
      {
        bibite: [
          { nome_portata: "Acqua", quantita_portata: 0 },
          { nome_portata: "Vino Rosso", quantita_portata: 0 },
          { nome_portata: "Vino Bianco", quantita_portata: 0 },
          { nome_portata: "Caffè", quantita_portata: 0 }
        ]
      }
    ],

然后我将我的对话框插入到一个 v-data-table 中,该对话框应该通过单击属性 item.nome 来触发,该属性是我的表的第一列

<v-data-table
                light
                :headers="headers_tabella_persone"
                :items="tabella_persone"
                :items-per-page="10"
                class="elevation-1"
              >
                <template v-slot:item.interno="{ item }">
                  <v-checkbox v-model="item.interno"></v-checkbox>
                </template>
                <template v-slot:item.nome="{ item }" @click="dialog_visualizza_menu=true">
                  <v-dialog v-model="dialog_visualizza_menu" scrollable max-width="300px">
                    {{item}}
                    <v-card>
                      <v-card-title>Seleziona primo</v-card-title>
                      <v-divider></v-divider>
                      <v-card-text style="height: 300px;">
                        <v-radio-group v-model="dialogm1" column>
                          <v-radio v-for="portata in menu_ristorante" :key="portata.primi"></v-radio>
                        </v-radio-group>
                      </v-card-text>
                      <v-divider></v-divider>
                      <v-card-title>Seleziona secondo</v-card-title>
                      <v-divider></v-divider>
                      <v-card-text style="height: 300px;">
                        <v-radio-group v-model="dialogm1" column>
                          <v-radio v-for="portata in menu_ristorante" :key="portata.secondi"></v-radio>
                        </v-radio-group>
                      </v-card-text>
                      <v-card-title>Seleziona bibite</v-card-title>
                      <v-divider></v-divider>
                      <v-card-text style="height: 300px;">
                        <v-radio-group v-model="dialogm1" column>
                          <v-radio v-for="portata in menu_ristorante" :key="portata.bibite"></v-radio>
                        </v-radio-group>
                      </v-card-text>
                      <v-card-actions>
                        <v-btn color="blue darken-1" text @click="dialog_visualizza_menu = false">Close</v-btn>
                        <v-btn color="blue darken-1" text @click="dialog_visualizza_menu = false">Save</v-btn>
                      </v-card-actions>
                    </v-card>
                  </v-dialog>
                </template>
              </v-data-table>

但是我在钥匙上收到这个错误作为回报

Avoid using non-primitive value as key, use string/number value instead.

所以我的整个列 item.nome 将不可见。如何设置引用菜单结构的有效原始键?

EDIT-1 我通过从我的对象中删除初始数组级别解决了密钥问题,这就是我更新的对象

menu_ristorante: {
  primi: [
    { id: 1, nome_portata: "Fettuccine al ragù", quantita_portata: 0 },
    {
      id: 2,
      nome_portata: "Tagliatelle alla boscaiola",
      quantita_portata: 0
    },
    { id: 3, nome_portata: "Spaghetti allo scoglio", quantita_portata: 0 },
    { id: 4, nome_portata: "Zuppa di ceci", quantita_portata: 0 },
    { id: 5, nome_portata: "Fettuccine al ragù", quantita_portata: 0 }
  ],
  secondi: [
    { id: 1, nome_portata: "Vitello tonnato", quantita_portata: 0 }
  ],
  contorni: [
    { id: 1, nome_portata: "Insalata mista", quantita_portata: 0 }
  ],
  bibite: [
    { id: 1, nome_portata: "Acqua", quantita_portata: 0 },
    { id: 2, nome_portata: "Vino Rosso", quantita_portata: 0 },
    { id: 3, nome_portata: "Vino Bianco", quantita_portata: 0 },
    { id: 4, nome_portata: "Caffè", quantita_portata: 0 }
  ]
},

模板是一样的

<template v-slot:item.nome="{ item }">
              <div style="cursor:pointer;" @click="popolaMenu()">{{item.nome}}</div>
            </template>
          </v-data-table>
        </v-tab-item>
        <v-dialog v-model="dialog_visualizza_menu" scrollable max-width="800px">
          <v-card>
            <v-card-title>Seleziona primo</v-card-title>
            <v-divider></v-divider>
            <v-card-text style="height: 800px;">                 
                <v-radio-group v-model="dialogm1" column>
                <v-radio v-for="(portata) in menu_ristorante" :key="portata.primi">{{portata.primi}}</v-radio>
              </v-radio-group>
            </v-card-text>
            <v-divider></v-divider>
            <v-card-title>Seleziona secondo</v-card-title>
            <v-divider></v-divider>
            <v-card-text style="height: 800px;">
              <v-radio-group v-model="dialogm1" column>
                <v-radio v-for="(portata) in menu_ristorante" :key="portata.secondi">{{portata.secondi}}</v-radio>
              </v-radio-group>
            </v-card-text>
            <v-card-title>Seleziona bibite</v-card-title>
            <v-divider></v-divider>
            <v-card-text style="height: 800px;">
              <v-radio-group v-model="dialogm1" column>
                <v-radio v-for="portata in menu_ristorante" :key="portata.bibite">{{portata.bibite}}</v-radio>
              </v-radio-group>
            </v-card-text>
            <v-card-actions>
              <v-btn color="blue darken-1" text @click="dialog_visualizza_menu = false">Close</v-btn>
              <v-btn color="blue darken-1" text @click="dialog_visualizza_menu = false">Save</v-btn>
            </v-card-actions>
          </v-card>
        </v-dialog>

我只是将它放在 v-data-table 的外部以避免递归调用,这会导致我的应用程序崩溃,所以现在如果我单击一个名称,则会显示弹出窗口,但它以错误的方式填充

在此处输入图像描述

标签: javascriptvue.js

解决方案


您正在使用对象作为键,这就是您收到该错误的原因。

一种快速的解决方法是像这样更改循环:

v-for="(portata, index) in menu_ristorante" :key="index"

但是,最好的办法是为每个迭代对象添加一个唯一 ID(字符串或整数)并将其用作键。

胃口大开;)


推荐阅读