Proper way to re-initialize the data in VueJs 2.0

浪子不回头ぞ 提交于 2019-11-30 06:22:59

问题


I was going through this answer on SO : Is there a proper way of resetting a component's initial data in vuejs?

However, the current method is not allowed now and VueJS prohibits changing the $data var.

As you can see here in this https://github.com/vuejs/vue/issues/2873 ( $data is not allowed to be modified. )

So if I try the above method, I am getting a VueJS warning:

[Vue warn]: Avoid replacing instance root $data. Use nested data properties instead.

Here is my JS code,

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?


回答1:


You can use Object.assign to iterate through all properties and assign them:

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/


Note: I'm using this.$options.data to call the original data method again to get a fresh copy of the data. No need for a separate initialState function. The data method is the initial state function.




回答2:


Did you try iterating through the initialState object and setting it again? 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.




回答3:


Wrap all the data into a dict with a key called "data" or other thing. Then you can re-initialize whole data by set this.data = {xx: yy}, or directly change one data item like 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!
        }
    }
}



回答4:


You can try this:

  1. Initialize your form data properties with required fields. (As seen in STEP 1)
  2. Create another data field that will be used to clone the form data you want to reset (As seen in STEP 2).
  3. Clone the form data required (STEP 3)
  4. Write you reset method (STEP 4)
  5. Use any where you prefer (STEP 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();
    },
  },
};



回答5:


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



来源:https://stackoverflow.com/questions/40340561/proper-way-to-re-initialize-the-data-in-vuejs-2-0

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!