Не допускать перезаписи данных - PullRequest
0 голосов
/ 30 октября 2018

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

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

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

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

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, в результате чего я не перезаписываю реквизит данных.

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

Ответы [ 3 ]

0 голосов
/ 30 октября 2018

@ Арман Чаран прав в своем ответе. Объект и массивы не примитивные типы, а ссылки.

Здесь есть отличное объяснение видео => JavaScript - Ссылка против примитивных значений / типов

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

Однако для вложенных массивов и объектов высокого уровня спид и 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's _.cloneDeep()

0 голосов
/ 30 октября 2018

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

Сначала установите lodash npm i 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>
0 голосов
/ 30 октября 2018

Проблема с побочным эффектом копирования 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)
  }

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