Создание локальной копии переданных реквизитов в дочернем компоненте в vue.js?

Как правильно редактировать опору в vue.js без изменения родительских данных? Я имею в виду, что всякий раз, когда мы передаем какое-либо свойство от родителя к потомку в vue.js, тогда, если мы вносим какие-либо изменения в это свойство в дочернем компоненте, это изменение также отражается в родительском компоненте.

Есть ли способ в vue.js сделать локальную копию переданного свойства в дочернем элементе?

Я погуглил, но везде написано, что этим можно добиться.

 props:["user"],
  data(){
    return {
      localUser: Object.assign({}, this.user)
    }
  }

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

Сталкивались ли вы с подобным сценарием, когда вам нужно внести изменения в родительское свойство в дочернем компоненте, не влияя на состояние родительского компонента, т.е. создать свою собственную копию в дочернем компоненте, а затем отредактировать ее?

Любая информация по этому поводу будет полезна.

Я также где-то читал, что в In vue @ 2.3.3 ,, когда мы хотим передать опору из компонента «Отец» в дочерний компонент, нам нужно вручную создать локальные данные для сохранения опоры, что делает много бесполезной работы.

мы можем вручную создать локальные данные следующим образом:

props: ['initialCounter'],
data: function () {
    return { counter: this.initialCounter }
}

но в моем случае это тоже не работает. Я использую vue cli 3.0.1 для целей разработки.

Вот мой код для того же.

В моем приложении есть список.

введите описание изображения здесь

Когда пользователь нажимает кнопку См. Сфокусированное представление, пользователь перенаправляется к указанному ниже представлению, то есть фактически является загрузочным - модальным представлением.

введите описание изображения здесь

Здесь пользователь может редактировать значение Name, но поскольку я передаю name здесь как свойство из aprent компонента, редактирование его здесь приводит к его обновлению и в родительском компоненте, то есть в представлении списка.


person Divyanshu Rawat    schedule 22.09.2018    source источник
comment
Кроме того, я уже пробовал этот {this.localUser = Object.assign ({}, this.user)}, а также this.localUser = JSON.parse (JSON.stringify (this.user))   -  person Divyanshu Rawat    schedule 22.09.2018
comment
Даже я пробовал lodash ._clone, хотя я решил проблему, привязав входные данные к локальной переменной в data () {x: null} и привязав @input = x, затем вызвав 2 функции set и unset, одна unsets отредактирована value в исходное значение, а other устанавливает его в x.   -  person Divyanshu Rawat    schedule 22.09.2018
comment
@DivyanshuRawat Использование Object.assign, как вы упомянули, должно работать, как показано в этой демонстрации.   -  person tony19    schedule 23.09.2018
comment
@ tony19 Привет, спасибо, вы правы, но видите, ваше решение не выполняется, когда вы загружаете данные из файла json в основное состояние app.vue, для получения дополнительной информации. пожалуйста, посмотрите репо. - github.com/divyanshu-rawat/stack-discuss Возможно, я ошибаюсь, но сделайте это исправь меня.   -  person Divyanshu Rawat    schedule 23.09.2018
comment
@ tony19, вы можете использовать эту скрипку для облегчения доступа - codeandbox.io/s/j4n13vxw6w   -  person Divyanshu Rawat    schedule 23.09.2018


Ответы (1)


В скрипке дочерний компонент использует Object.assign() для создания копия data, который представляет собой массив объектов. Однако при этом создается только неглубокая копия, поэтому элементы массива по-прежнему будут ссылаться на исходный экземпляров, что приводит к наблюдаемому вами поведению.

Несколько решений для глубокого копирования массива:

  • Используйте JSON.parse(JSON.stringify(this.data)), который работает разумно. хорошо для объектов строк и чисел:

    data() {
      return {
        local_data: JSON.parse(JSON.stringify(this.data))
      }
    }
    

    (демонстрация 1)

  • Сопоставьте объекты с новыми, что хорошо работает, если глубина всего 1 (вложенные массивы / объекты все равно будут неглубоко скопированы):

    data() {
      return {
        local_data: this.data.map(x => ({...x}))
      }
    }
    

    (демонстрация 2)

  • Используйте служебную библиотеку, например cloneDeep lodash:

    data() {
      return {
        local_data: _.cloneDeep(this.data)
      }
    }
    

    (демонстрация 3)

person tony19    schedule 23.09.2018
comment
Это было отличное объяснение, которое мне понадобилось после нескольких часов, когда я никуда не попал. - person Chase Ernst; 17.09.2020
comment
Это очень помогает, мне нравятся многочисленные примеры. Есть ли в демонстрации 1 проблемы с объектами даты в массивах? - person Caine Nielsen; 10.11.2020
comment
@CaineNielsen JSON.stringify преобразует объекты Date в String (через Date#toString), поэтому их нужно будет возродить в JSON.parse < / а>. - person tony19; 10.11.2020
comment
отличный ответ, но имейте в виду, что демонстрация 2 менее мелкая, но все же мелкая копия (глубина 1) this.data.map(x => ({...x})) - если ваш массив содержит объекты с объектами или массивами в них, это будет неглубокая копия. - person Tom Carchrae; 05.06.2021
comment
@TomCarchrae Хорошее замечание. К этому решению добавлено предостережение. - person tony19; 05.06.2021