如何克隆道具对象并使其无反应

A.C*_*A.C 11 vue.js

我有一些表单数据,我通过道具与子组件共享。现在我想克隆 prop 对象并使其无反应。就我而言,我希望用户能够在不实际更改克隆值的情况下修改 props 值。克隆值应该只用于向用户显示编辑时表单的内容。下面的代码显示了这一点:

    <template>
        <div>
            <div v-if="computedFormData">
                original prop title: {{orgData.title}}

                new title:
                <input type="text" v-model="formData.title"/> 
                //changing data here will also change orgData.title
            </div>

        </div>
    </template>

    <script>
        export default {
            props: ['formData'],
            data() {
                return {
                    orgData: [],
                }
            },
            computed: {
                computedFormData: function () {
                    this.orgData = this.formData;
                    return this.orgData;
                },
            },
            methods: {
            },
        }
    </script>
Run Code Online (Sandbox Code Playgroud)

我试过Object.freeze(testData);但它不起作用,testData 和 orgData 都是反应性的。另请注意,使用mountedcreated属性不会呈现 orgData,因此我被迫使用该computed属性。

Yom*_* S. 10

尝试使用Object.assign复制 prop 值。不再有反应性问题,因为新分配的值只是副本而不是对源的引用。

如果您的数据对象要复杂得多,我建议使用deepmerge代替Object.assign.

Vue.component('FormData', {
  template: `
    <div>
      <div v-if="testData">
        <p>Original prop title: <strong>{{orgData.title}}</strong></p> 
        <p>Cloned prop title:</p>
        <input type="text" v-model="testData.title" />
      </div>
    </div>
  `,

  props: ['orgData'],

  data() {
    return {
      testData: Object.assign({}, this.orgData)
    }
  }
});

const vm = new Vue({
  el: '#app',

  data() {
    return {
      dummyForm: {
        title: 'Some title'
      }
    }
  }
});
Run Code Online (Sandbox Code Playgroud)
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>

<div id="app">
  <form-data :org-data="dummyForm"></form-data>
</div>
Run Code Online (Sandbox Code Playgroud)


小智 8

Object.assign 只是一个浅拷贝。如果您有一个仅包含原始数据类型(字符串、数字、bigint、布尔、未定义、符号和 null)的副本,那就没问题。它消除其反应性。但是,如果您有一个包含引用类型的副本,您可以\xe2\x80\x99t浅克隆它以删除其反应性

\n

对于 depping 克隆,您可以使用JSON.parse(JSON.stringify())模式。但请记住,如果您的数据包含受支持的JSON 数据类型,那么这将起作用。

\n
  props: [\'orgData\'],\n\n  data() {\n    return {\n      cloneOrgData: JSON.parse(JSON.stringify(this.orgData))\n    }\n  }\n
Run Code Online (Sandbox Code Playgroud)\n