Старайтесь не мутировать опору напрямую - Datatable VueJS - PullRequest
0 голосов
/ 11 марта 2020

Я новичок в Vue JS, и у меня возникла эта проблема. Я пытаюсь создать таблицу данных. Передав родительский реквизит child

Я получил эту ошибку

[Vue warn]: Старайтесь не менять объект напрямую, так как значение будет перезаписываться при повторной визуализации родительского компонента. Вместо этого используйте данные или вычисляемое свойство, основанное на значении реквизита. Подставка изменена: "editedItem"


Вот мой код

это моя страница:

<template >
  <v-container  >

    <v-col>
     <Datatables
      :headers="this.headers"
      :items="items"
      :editedItem="this.editedItem"
      :defaultItem="defaultItem"
      sort-by="calories"
      class="elevation-1" />
    </v-col>
  <v-spacer></v-spacer>
  <br>
    <v-col>

    </v-col>
  </v-container >
</template>

<script>

import Datatables from '../../components/Datatable/CrudDatatable'
export default {

  components:{

    Datatables

  },
  data() {
   return {

      headers: [
        {
          text: 'Dessert (100g serving)',
          align: 'start',
          sortable: false,
          value: 'name',
        },
        { text: 'Calories', value: 'calories' },
        { text: 'Fat (g)', value: 'fat' },
        { text: 'Carbs (g)', value: 'carbs' },
        { text: 'Protein (g)', value: 'protein' },
        { text: 'Actions', value: 'action', sortable: false },
      ],
      items: [],
      editedItem: {
        name: '',
        calories: 0,
        fat: 0,
        carbs: 0,
        protein: 0,
      },
      defaultItem: {
        name: '',
        calories: 0,
        fat: 0,
        carbs: 0,
        protein: 0,
      },


   }
 },
  created () {
      this.initialize()
    },
    methods: {
       initialize () {
        this.items = [
          {
            name: 'Frozen Yogurt',
            calories: 159,
            fat: 6.0,
            carbs: 24,
            protein: 4.0,
          },
          {
            name: 'Ice cream sandwich',
            calories: 237,
            fat: 9.0,
            carbs: 37,
            protein: 4.3,
          },
        ]
      },



    },


}



</script>


<style>

</style>


Это мой компонент:

<template>
  <v-data-table :headers="headers" :items="items" sort-by="calories" class="elevation-1">
    <template v-slot:top>
      <v-toolbar flat color="white">
        <v-toolbar-title>My CRUD</v-toolbar-title>
        <v-divider class="mx-4" inset vertical></v-divider>
        <v-spacer></v-spacer>
        <v-dialog v-model="dialog" max-width="500px">
          <template v-slot:activator="{ on }">
            <v-btn color="primary" dark class="mb-2" v-on="on">New Item</v-btn>
          </template>
          <v-card>
            <v-card-title>
              <span class="headline">{{ formTitle }}</span>
            </v-card-title>

            <v-card-text>
              <v-container>
                <v-row>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.name" label="Dessert name"></v-text-field>
                  </v-col>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.calories" label="Calories"></v-text-field>
                  </v-col>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.fat" label="Fat (g)"></v-text-field>
                  </v-col>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.carbs" label="Carbs (g)"></v-text-field>
                  </v-col>
                  <v-col cols="12" sm="6" md="4">
                    <v-text-field v-model="editedItem.protein" label="Protein (g)"></v-text-field>
                  </v-col>
                </v-row>
              </v-container>
            </v-card-text>

            <v-card-actions>
              <v-spacer></v-spacer>
              <v-btn color="blue darken-1" text @click="close">Cancel</v-btn>
              <v-btn color="blue darken-1" text @click="save">Save</v-btn>
            </v-card-actions>
          </v-card>
        </v-dialog>
      </v-toolbar>
    </template>
    <template v-slot:item.action="{ item }">
      <v-icon small class="mr-2" @click="editItem(item)">mdi-pencil</v-icon>
      <v-icon small @click="deleteItem(item)">mdi-delete</v-icon>
    </template>
    <template v-slot:no-data>
      <v-btn color="primary" @click="initialize">Reset</v-btn>
    </template>
  </v-data-table>
</template>
<script>
export default {
  props: {
    headers: {
      type: Array
    },
    items: {
      type: Array
    },
    editedItem: {
      type: Object
    },
    defaultItem: {
      type: Object
    }
  },
  data: () => ({
    dialog: false,
    editedIndex: -1,
  }),

  computed: {
    formTitle() {
      return this.editedIndex === -1 ? "New Item" : "Edit Item";
    }
  },

  watch: {
    dialog(val) {
      val || this.close();
    }
  },
  created () {
      this.getParentItem()
    },
  methods: {

    getParentItem(){



    },

    editItem(item) {
      this.editedIndex = this.items.indexOf(item);
      this.editedItem = Object.assign({}, item);
      this.dialog = true;
    },

    deleteItem(item) {
      const index = this.items.indexOf(item);
      confirm("Are you sure you want to delete this item?") &&
        this.items.splice(index, 1);
    },

    close() {
      this.dialog = false;
      setTimeout(() => {
        this.editedItem = Object.assign({}, this.defaultItem);
        this.editedIndex = -1;
      }, 300);
    },

    save() {
      if (this.editedIndex > -1) {
        Object.assign(this.items[this.editedIndex], this.editedItem);
      } else {
        this.items.push(this.editedItem);
      }
      this.close();
    }
  }
};
</script>



1 Ответ

0 голосов
/ 11 марта 2020

Добавьте некоторые переменные данных, которые установлены для переменных prop в created вашего компонента. Например:

this.internalItems = this.items
this.internalEditedItem = this.editedItem

Затем в ваших методах отредактируйте их вместо переменных проп.

this.internalEditedItem = Object.assign({}, item);
...
Object.assign(this.items[this.editedIndex], this.internalEditedItem);
...etc

Если вы планируете модифицировать реквизиты от родителя, вам также необходимо добавить следите за переменными, чтобы сбросить их до новых значений.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...