【问题标题】:Vue copying of object to local dataVue将对象复制到本地数据
【发布时间】:2019-03-13 08:24:45
【问题描述】:

我正在尝试将数据从道具复制到本地 data() 值以进行编辑,但是当我进行更改时它会继续编辑。

export default {
  props: {
    item: {
      type: Object,
      required: true
    }
  },
  data () {
    return {
      form: { ...this.item }
    }
  }
}

然后我将本地表单数据的 Translations 属性传递给另一个组件,该组件处理编辑

<tab
   v-for="translation in form.translations"
   :key="translation.locale.value"
   :name="translation.locale.value">
   <form-group :fields="translation" />
</tab>

在我的 FormGroup 组件中,我收到传递的字段,将它们过滤掉,这样隐藏的就不会出现,然后编辑它们。

现在,当我进行编辑时,我在 Vue 检查器中看到我的父组件中的原始项目也在被编辑。

<script>
export default {
  props: {
    fields: {
      type: Object,
      required: true
    }
  },
  computed: {
    filtered () {
      return Object.keys(this.fields)
        .filter(field => this.fields[field].type !== 'hidden')
        .reduce((res, field) => Object.assign(res, { [field]: this.fields[field] }), {})
    }
  }
}
</script>

【问题讨论】:

    标签: javascript vue.js


    【解决方案1】:

    因为你在内存中编辑的对象是同一个引用,比如Array、Function和Object。

    像这样,使用Object.assign():

    let obj1 = { a: 0 , b: { c: 0}};
    let obj2 = Object.assign({}, obj1);
    console.log(JSON.stringify(obj2)); // { a: 0, b: { c: 0}}
    

    然后编辑obj2:

    obj2.a = 33
    console.log(obj1)  // { a: 0 , b: { c: 0}}
    

    【讨论】:

    • 感谢帮助,我尝试格式化代码但没有成功
    【解决方案2】:
    // Deep Clone, as per MDN web docs 
      obj1 = { a: 0 , b: { c: 0}};
      let obj3 = JSON.parse(JSON.stringify(obj1));
      obj1.a = 4;
      obj1.b.c = 4;
      console.log(JSON.stringify(obj3)); // { a: 0, b: { c: 0}}
    

    https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

    对象是非原始的,不像数字、字符串、布尔值等。这意味着它们是通过引用而不是值来解析的。

    因此,一个对象的变化,即使是跨组件,即使它们是 props,你实际上并不是从 child 更改 prop,而是从 parent,并且重新解析新版本,作为更新版本支柱。

    export default {
        props: {
            data: {
                type: Object,
                required: true
            }
        },
    
        computed: {
            clonedData() {
                return JSON.parse(JSON.stringify(this.data))
            }
        }
    }
    

    阅读更多关于参考与价值的信息 https://codeburst.io/explaining-value-vs-reference-in-javascript-647a975e12a0

    【讨论】:

    • 嗯,这行得通,但它看起来很hacky?为什么这行得通而我上面的代码却不行?
    • 因为对象被解析为引用,不像基本类型,如数字、字符串、布尔等。所以你改变了引用的对象。 codeburst.io/…
    • 所以我需要一个深度克隆,对吧?没有 JSON 方法可以吗?
    • 不是我的知识伙伴,但我很乐意承认我不是一个无所不知的神谕;)我以前用过 Deep Watchers,没听说过 Deep Copy。
    • 我的意思是深度克隆,抱歉,我最终使用了 lodash 的 cloneDeep 方法,该方法现在可以完美运行,您的解决方案也可以正常工作,除非它会丢弃对象中存在的 Function 和 Infinite 类型。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-12-02
    • 1970-01-01
    • 2020-11-06
    • 2019-03-28
    相关资源
    最近更新 更多