@ArutaGerman

Почему push 2 массива добавляет?

Задача:
Реализовать кнопку отката последнего действия.

Как работает:
Текущие данные записываются в массив history, по нажатию на кнопку apply, на кнопке undo откатывается, при этом значения в input меняются на предыдущие - всё отлично, хоть до 100500 шагов так, но это только если не нажимать кнопку undo.
history: [ { "0": "", "1": "test" }, 
               { "0": "test", "1": "test" }, 
               { "0": "test", "1": "test", "2": "test"} 
]


Если хотя бы раз нажать кнопку undo, то при следующей записи новых данных в массив он пишет и v-model (ключи name, surname и т.д.) и input.value (индексы), а дальше снова нормально - только input.value
history: [ 
              { "0": "", "1": "test"}, 
              { "0": "test", "1": "test", "2": "", "3": "", "4": "", "5": "asd", "6": "", "surname": "test", "name": "test", "secondName": "", "phone": "", "phone2": "", "mail": "", "address": "" } ]


Почему добавляются и эти значения ["surname": "test", "name": "test", "....], если нажать undo и потом добавить новые значения?

Ниже код компонента:
<template>
  <div class="wrapper">
    <form>
      <div
        v-for="(n, index) in meta"
        :key="(index += 1)"
        class="form__other-data"
      >
        <span class="form__other-title">
          {{ n.title }}
        </span>
        <input
          v-model="contact[n.name]"
          :type="n.type"
          :value="contact[n.name]"
          :disabled="disabled"
        />
      </div>
    </form>
    <div>
      <button @click="edit">Edit</button>
      <button @click="apply">Подтвердить</button>
      <button @click="saveChanges">Сохранить</button>
    </div>
    <button v-if="this.history.length > 0" @click="undo">Кнопка назад</button>
    <div>history: {{ history }}</div>
    <br />
    <br />
    <div>temp: {{ temp }}</div>
    <br />
    <br />
    <div>newData: {{ newData }}</div>
    <br />
    <br />
    <div>contact: {{ contact }}</div>
  </div>
</template>

<script>
export default {
  props: ["contact"],
  data() {
    return {
      oneStepMode: true, //режим для регулирования
      onUndoMode: false, //режим возврата активирован
      disabled: true, //режим disabled для input
      initData: [], //массив для сохранения первоначальных данных
      history: [], //массив истории действий
      newData: [], //массив новых данных, в котором хранятся данные из объекта temp и которые будут передаваться в книгу контактов как конечный результат для текущего контакта
      temp: {}, //объект для хранения данных введенных на каждой итерации до нажатия кнопки "Подтвердить изменения"
      meta: [
        { name: "surname", title: "Фамилия", type: "text" },
        { name: "name", title: "Имя", type: "text" },
        { name: "secondName", title: "Отчество", type: "text" },
        { name: "phone", title: "Телефон", type: "text" },
        { name: "phone2", title: "Телефон", type: "text" },
        { name: "mail", title: "E-mail", type: "text" },
        { name: "address", title: "Адрес", type: "text" },
      ],
    };
  },

  mounted() {
    let key = document.querySelectorAll("input");
    //при загрузке изначальные значения помещаем в промежуточный массив
    for (let i = 0; i < key.length; i++) {
      this.initData.push(key[i].value);
    }
    //преобразуем полученный массив в объект и помещаем первым в массив истории действий, для возможности отката к нему
    this.history.push({ ...this.initData });
  },

  methods: {
   
    apply() {                        //кнопка подтверждения изменений
      if (!this.onUndoMode) {
        let input = document.querySelectorAll("input");
        for (let i = 0; i < this.meta.length; i++) {       //длина массива meta взята, чтобы при откате изменений на начальные значения, не было undefined 
          this.temp[i] = input[i].value;
        }
        this.history.push(this.temp);
        this.temp = {};
        this.disabled = !this.disabled;
        this.oneStepMode = false
      }
    },
    //кнопка отката на предыдущий шаг (назад)
    undo() {
      let input = document.querySelectorAll("input");
      let history = this.history;
      let meta = this.meta;
      let newData = this.newData;
      let temp = this.temp;
      let last;
        if (history.length > 1) {   //если длина history больше 1, то откатывать на предыдущий шаг, который записан в history
          if (this.oneStepMode == false) {     //этот блок для чтения предпоследнего элемента массива и вставить это значение в input
            history.splice(history.length - 1, 1);
            last = history.pop();
            this.oneStepMode = true;   
          } else {     //если history длина 1, то данные в input будут равны тем, что при загрузке страницы были
            last = history.pop();
          }
        } else {
          last = this.initData;
        }
        this.onUndoMode = true;
        this.$nextTick(() => {
          this.onUndoMode = false;
        }, 0);
        //считываем данные из массива history для отображения в input предыдущих введенных данных (предыдущий шаг)
        for (let i = 0; i < meta.length; i++) {
          temp[meta[i].name] = last[i];
          newData = temp;
          input[i].value = newData[meta[i].name];
          this.contact[meta[i].name] = input[i].value;
        }              
    },
    //кнопка доступа в режим редактирования
    edit() {
      this.oneStepMode = true;
      this.disabled = !this.disabled;
    },
  },
};
</script>
  • Вопрос задан
  • 47 просмотров
Пригласить эксперта
Ответы на вопрос 1
xcodervv
@xcodervv
Фронтенд разработчик
Чтобы быстрее всего разобраться в дублировании данных, выводите в консоль ваш history в тех местах ,где у вас идет работа с массивом history.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы