简体   繁体   English

在VueJs 2.0中重新初始化数据的正确方法

[英]Proper way to re-initialize the data in VueJs 2.0

I was going through this answer on SO : Is there a proper way of resetting a component's initial data in vuejs? 我在SO上回答这个问题: 是否有正确的方法在vuejs中重置组件的初始数据?

However, the current method is not allowed now and VueJS prohibits changing the $data var. 但是,现在不允许使用当前方法,VueJS禁止更改$ data var。

As you can see here in this https://github.com/vuejs/vue/issues/2873 ( $data is not allowed to be modified. ) 正如您在此https://github.com/vuejs/vue/issues/2873中所见($ data不允许修改。)

So if I try the above method, I am getting a VueJS warning: 所以如果我尝试上面的方法,我会得到一个VueJS警告:

[Vue warn]: Avoid replacing instance root $data. [Vue警告]:避免替换实例根$ data。 Use nested data properties instead. 请改用嵌套数据属性。

Here is my JS code, 这是我的JS代码,

function initialState () {
        return {
            h2: 0,
            ch4: 0,
            c2h6: 0,
            c2h4: 0,
            c2h2: 0,
            c3h8: 0,
            c3h6: 0,
            co: 0,
            co2: 0,
            o2: 0,
            n2: 0,
            selected: ''
        }
    }
    export default {
        name: 'something',
        data () {
            return initialState() // This is working fine 
        },
        computed: {
            tdcg: function () {
                // some logic here...
            }
        },
        methods: {
            resetFields: function () {
                this.$data = initialState() // --> This is what I want to achieve!
            }
        }
    }

So what is the correct and the easiest way of re initialising my data? 那么重新初始化数据的正确和最简单的方法是什么?

You can use Object.assign to iterate through all properties and assign them: 您可以使用Object.assign遍历所有属性并分配它们:

export default {
    data () {
        return {
            h2: 0,
            // other attributes...
        };
    },
    methods: {
        resetFields () {
            Object.assign(this.$data, this.$options.data.call(this));
        }
    }
}

Here's a demo fiddle: https://jsfiddle.net/797yyvtz/ 这是一个演示小提琴: https//jsfiddle.net/797yyvtz/


Note: I'm using this.$options.data to call the original data method again to get a fresh copy of the data. 注意:我正在使用this.$options.data再次调用原始data方法以获取data的新副本。 No need for a separate initialState function. 不需要单独的initialState函数。 The data method is the initial state function. data方法初始状态函数。

Did you try iterating through the initialState object and setting it again? 您是否尝试迭代initialState对象并再次设置它? Here is the sample code: 以下是示例代码:

function initialState() {
    return {
        h2: 0,
        ch4: 0,
        // and so on... finally
        selected: ''
    }
}

export default {
    name: 'something',
    data: function() {
        return initialState()
    },
    computed: {
        // ...
    },
    methods: {
        resetFields: function() {
            // Fetch the initialState object locally, so we do not have to call the function again
            let initialData = initialState();
            // Iterate through the props
            for (let prop in initialData) {
                // Reset the prop locally.
                this[prop] = initialData[prop];
            }
        }
    }
}

In my limited experiments locally, it does seem to work. 在我本地有限的实验中,它似乎确实有效。 Let me know your thoughts on this method. 让我知道你对这种方法的看法。

Wrap all the data into a dict with a key called "data" or other thing. 使用名为“data”或其他内容的键将所有数据包装到dict中。 Then you can re-initialize whole data by set this.data = {xx: yy}, or directly change one data item like this.data.h2 = 2. 然后你可以通过设置this.data = {xx:yy}重新初始化整个数据,或直接更改一个数据项,如this.data.h2 = 2。

function initialState () {
    return {
        h2: 0,
        ch4: 0,
        c2h6: 0,
        c2h4: 0,
        c2h2: 0,
        c3h8: 0,
        c3h6: 0,
        co: 0,
        co2: 0,
        o2: 0,
        n2: 0,
        selected: ''
    }
}
export default {
    name: 'something',
    data () {
        return {data: initialState()} // This is working fine 
    },
    computed: {
        tdcg: function () {
            // some logic here...
        }
    },
    methods: {
        resetFields: function () {
            this.data = initialState() // --> This is what I want to achieve!
        }
    }
}

You can try this: 你可以试试这个:

  1. Initialize your form data properties with required fields. 使用必填字段初始化表单数据属性。 (As seen in STEP 1) (如步骤1中所示)
  2. Create another data field that will be used to clone the form data you want to reset (As seen in STEP 2). 创建另一个数据字段,用于克隆要重置的表单数据(如步骤2中所示)。
  3. Clone the form data required (STEP 3) 克隆所需的表单数据(步骤3)
  4. Write you reset method (STEP 4) 写你重置方法(步骤4)
  5. Use any where you prefer (STEP 5) 使用您喜欢的任何地方(步骤5)

 export default { // Initialize your data data() { return { // Initialize the form field (STEP 1) formFields: { name: '', email: '', password: '', moreData: { field1: '', field2: [], }, }, // Create an object property used for cloning (STEP 2) formFieldsCopy: {}, }; }, // When the DOM is mounted copy the // formField you want to a temporary field // You can use lodash ._clone or ES6 spread operator (STEP 3) mounted() { this.formFieldsCopy = { ...this.formFields }; }, methods: { // Write the function to reset the form (STEP 4) resetFormFields() { this.formFields = { ...this.formFieldsCopy }; }, submit() { // Do you normal Axios requests here // and call you reset function. (STEP 5). this.resetFormFields(); }, }, }; 

My solution: 我的解决方案

mounted(){
    this.saveData() // you can load if you need previous data
},
methods: {
    saveData(){
        localStorage.setItem(this.$options.name,JSON.stringify(this.$data));
    },
    loadData(){
        if (localStorage.getItem(this.$options.name) !== null) {
            let data= JSON.parse(localStorage.getItem(this.$options.name));
            Object.keys(data).forEach((key)=>{this[key] = data[key];});
        }
    }
}

When you need you can load or save them again 如果需要,您可以再次加载或保存它们

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM