Не допускать перезаписи данных

1

Я новичок в vue.js и борюсь со следующим сценарием. Я отправляю массив, заполненный объектами через реквизиты, на мой маршрутизатор.

Внутри одного из компонентов моего маршрутизатора я использую этот массив в нескольких функциях, ссылаюсь на него с помощью this.data и сохраняю его внутри функций в новой переменной, поэтому я не перезаписываю фактические данные prop.

Однако функции перезаписывают исходные данные прокрутки и манипулируют данными опоры.

Вот абстрактный пример моего вопроса:

App.vue

<template>
  <div>
    <router-view :data='data'></router-view>
  </div>
</template>

<script>
export default {
  data: function() {
    return {
      data: [],
    };
  },

  created: function() {
    this.getData();
  },

  methods: {
    getData: function() {
      this.data = // array of objects
    },
  }

компонент маршрута:

<script>
export default {

  props: {
    data: Array,
  },

  data: function() {
    return {
      newData1 = [],
      newData2 = [],
    }
  }

  created: function() {
    this.useData1();
    this.useData2();
  },

  methods: {
    useData1: function() {
      let localData = this.data;
      // do something with 'localData'
      this.newData1 = localData;
    }

    useData2: function() {
      let localData = this.data;
      // do something with 'localData'
      this.newData2 = localData;
    }
  }
}
</script>

"LocalData" в useData2 управляется из изменений в useData1, в результате чего я не перезаписываю данные.

Почему я перезаписываю опору и как могу ее предотвратить?

Теги:
vue.js
vuejs2

3 ответа

0
Лучший ответ

Я думаю, что это наиболее читаемый, "декларативный" способ:

Сначала установите lodash npm я lodash. Затем импортируйте нужную функцию, а не всю библиотеку, и инициализируйте свои данные массивом из реквизита.

<script>
  import cloneDeep from 'lodash/cloneDeep'

  export default {
    props: {
      data: Array
    },

    data () {
      return {
        // initialize once / non reactive
        newData1: cloneDeep(this.data),
        newData2: cloneDeep(this.data)
      }
    }
  }
</script>
1

@Arman Charan прав на его ответ. Объект и массивы - это не примитивные типы, а ссылки.

Здесь есть удивительное видеообращение => JavaScript - Reference vs Primitive Values /Types

Поэтому для ссылочных типов вам сначала нужно клонировать его на другую переменную, а затем изменять эту переменную без изменений, влияющих на исходные данные.

Однако для вложенных массивов и объектов на высоком уровне spead и Array.from не будут работать.

Если вы используете Lodash, вы можете использовать _.cloneDeep() для безопасного клонирования массива или объекта.

Мне нравится функциональное программирование, и я использую Lodash, который я настоятельно рекомендую.

Таким образом, вы можете:

let original_reference_type = [{ id:1 }, { id: 2 }]
let clone_original = _.cloneDeep(original_reference_type)

clone_original[0].id = "updated"
console.log(original_reference_type) //[{ id:1 }, { id: 2 }] => will not change
console.log(clone_original) // [{ id: "updated" }, { id: 2 }]

Предложение: для простых массивов и объектов используйте:

Объекты:

let clone_original_data = {...original_data} или

let clone_original_data = Object.assign({}, original_data)

Массивы:

let clone_original_data = [...original_data] или

let clonse_original_data = original_data.slice()

Для сложных и высоких вложенных массивов или объектов идут с Lodash _.cloneDeep()

1

Проблема, с которой вы сталкиваетесь в побочном эффекте копирования this.data по ссылке, а не на значение.

Решение заключается в использовании техники, обычно называемой клонированием. Массивы обычно клонируются с использованием синтаксиса распространения или Array.from().

См. Ниже практический пример.

// Methods.
methods: {

  // Use Data 1.
  useData1: function() {
    this.newData1 = [...this.data]
  },

  // Use Data 2.
  useData2: function() {
    this.newData2 = Array.from(this.data)
  }

}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню