vuetify данные почему в диалоговых окнах данные повторяются?

Имеется data-table:

<v-data-table
            :headers="headers"
            :items="items"
        >
            <template v-slot:item.action="{ item }">
                <v-dialog
                    v-model="dialog_destroy"
                    max-width="400"
                >
                    <template v-slot:activator="{ on, attrs }">
                        <v-btn
                            color="red"
                            dark
                            small
                            depressed
                            outlined
                            v-bind="attrs"
                            v-on="on"
                        >Удалить контакт</v-btn>
                    </template>
                    <v-card>
                        <v-card-title>
                            <span class="headline">Удалить контакт: @{{ item.contact_name }}</span>
                        </v-card-title>
                        <v-card-text>Вы действительно хотите удалить контакт?</v-card-text>
                        <v-card-actions>
                            <v-btn
                                color="green"
                                text
                                v-bind:href="item.destroy_link"
                            >Подтвердить</v-btn>
                            <v-spacer></v-spacer>
                            <v-btn
                                text
                                v-on:click="dialog_destroy = false"
                            >Отменить</v-btn>
                        </v-card-actions>
                    </v-card>
            </template>
        </v-data-table>

Имеется скрипт:

<script>
        new Vue({
            el: '#app',
            vuetify: new Vuetify(),
            data: () => ({
                drawer: true,
                dialog_info: false,
                dialog_destroy: false,
                headers: [{
                    text: 'Контактное лицо',
                    value: 'contact_name',
                    align: 'start'
                }, {
                    text: 'Телефон',
                    value: 'phone',
                    align: 'center'
                }, {
                    text: 'Страна, город',
                    value: 'country',
                    align: 'center'
                }, {
                    text: 'Точный адрес',
                    value: 'address',
                    align: 'center'
                }, {
                    text: 'Время доставки',
                    value: 'delivery_time',
                    align: 'center'
                }, {
                    value: 'action',
                    align: 'end',
                    sortable: false
                }],
                items: [{"contact_name":"#222","phone":"#222","country":"#222","address":"#222","delivery_time":"#222","comment":"#222","edit_link":"http:\/\/127.0.0.1:8000\/dashboard\/contacts\/edit\/2","destroy_link":"http:\/\/127.0.0.1:8000\/dashboard\/contacts\/2\/destroy"},{"contact_name":"No Name","phone":"88001234567sda","country":"dsasdasda","address":"asdsdadsa","delivery_time":"10:00 - 12:00","comment":"asdsdasaddsa","edit_link":"http:\/\/127.0.0.1:8000\/dashboard\/contacts\/edit\/1","destroy_link":"http:\/\/127.0.0.1:8000\/dashboard\/contacts\/1\/destroy"}]
            })
        })
    </script>

Подскажите, пожалуйста, почему при нажатии на "удалить окно"(при открытии диалогового окна) данные item.contact_name повторяются?


Ответы (1 шт):

Автор решения: Не быть рабом на Руси
  1. Я не смог воспроизвести дублирование данных.
  2. В приведённом примере не было закрывающего тега </v-dialog>.
  3. Правильней не создавать компонент диалога в каждой строке таблицы, а вынести его из итерации. Так как исходя из задачи, вам необходимо только подтвердить действие.

Ниже приведён код с вынесеным диалогом.

new Vue({
  el: '#app',
  vuetify: new Vuetify(),
  data() {
    return {
      drawer: true,
      dialog_info: false,
      dialog_destroy: false,
      removed_item: null,
      headers: [{
        text: 'Контактное лицо',
        value: 'contact_name',
        align: 'start'
      }, {
        text: 'Телефон',
        value: 'phone',
        align: 'center'
      }, {
        text: 'Страна, город',
        value: 'country',
        align: 'center'
      }, {
        text: 'Точный адрес',
        value: 'address',
        align: 'center'
      }, {
        text: 'Время доставки',
        value: 'delivery_time',
        align: 'center'
      }, {
        value: 'action',
        align: 'end',
        sortable: false
      }],
      items: [{
        "contact_name": "#222",
        "phone": "#222",
        "country": "#222",
        "address": "#222",
        "delivery_time": "#222",
        "comment": "#222",
        "edit_link": "http:\/\/127.0.0.1:8000\/dashboard\/contacts\/edit\/2",
        "destroy_link": "http:\/\/127.0.0.1:8000\/dashboard\/contacts\/2\/destroy"
      }, {
        "contact_name": "No Name",
        "phone": "88001234567sda",
        "country": "dsasdasda",
        "address": "asdsdadsa",
        "delivery_time": "10:00 - 12:00",
        "comment": "asdsdasaddsa",
        "edit_link": "http:\/\/127.0.0.1:8000\/dashboard\/contacts\/edit\/1",
        "destroy_link": "http:\/\/127.0.0.1:8000\/dashboard\/contacts\/1\/destroy"
      }]
    };
  },
  
  computed: {
    removed_name() {
      return this.removed_item 
        ? this.removed_item.contact_name
        : '';
    }
  },
  methods: {
  
    toggleDialog() {
      this.dialog_destroy = !this.dialog_destroy;
    },
    
    removeAlert(item) {
      this.removed_item = item;
      
      this.toggleDialog();
    },
    
    remove() {
      const index = this.items.indexOf(this.removed_item);
      
      this.items.splice(index, 1);
      
      this.toggleDialog();
    },
  },
})
<link href="https://fonts.googleapis.com/css?family=Roboto:100,300,400,500,700,900" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/@mdi/[email protected]/css/materialdesignicons.min.css" rel="stylesheet">
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.min.css" rel="stylesheet">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vuetify.js"></script>
<div 
  data-app
  id="app"
>
  <v-dialog
    v-model="dialog_destroy"
    max-width="400"
  >
    <v-card>
      <v-card-title>
        <span class="headline">
          Удалить контакт: {{ removed_name }}
        </span>
      </v-card-title>
      <v-card-text>
        Вы действительно хотите удалить контакт?
      </v-card-text>
      <v-card-actions>
        <v-btn 
          color="green"
          text
          @click="remove"
        >
          Подтвердить
        </v-btn>
        <v-spacer></v-spacer>
        <v-btn 
          text 
          @click="toggleDialog"
        >
          Отменить
        </v-btn>
      </v-card-actions>
    </v-card>
  </v-dialog>

  <v-data-table
    :headers="headers"
    :items="items"
  >
    <template v-slot:item.action="{ item }">
      <v-btn
        color="red"
        small
        depressed
        outlined
        @click="removeAlert(item)"
      >
        Удалить контакт
      </v-btn>
    </template>
  </v-data-table>
</div>

→ Ссылка