A
A
ArutaGerman2021-01-22 11:15:12
Vue.js
ArutaGerman, 2021-01-22 11:15:12

Why does push 2 add arrays?

Task:
Implement a rollback button for the last action.

How it works: The
current data is written to the history array, when the apply button is pressed, it is rolled back on the undo button, while the values ​​in the input change to the previous ones - everything is fine, even up to 100500 steps, but this is only if the undo button is not pressed.

history: [ { "0": "", "1": "test" }, 
               { "0": "test", "1": "test" }, 
               { "0": "test", "1": "test", "2": "test"} 
]


If you press the undo button at least once, then the next time new data is written to the array, it writes both v-model (keys name, surname, etc.) and input.value (indices), and then it’s normal again - only 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": "" } ]


Why are these values ​​["surname": "test", "name": "test", "....] also added if I press undo and then add new values?

Below is the component code:
<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>

Answer the question

In order to leave comments, you need to log in

1 answer(s)
V
Valery Voronkov, 2021-01-22
@xcodervv

The fastest way to figure out duplication of data is to output your history to the console in those places where you are working with the history array.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question