【问题标题】:Proper way to re-initialize the data in VueJs 2.0在 VueJs 2.0 中重新初始化数据的正确方法
【发布时间】:2017-03-13 10:34:29
【问题描述】:

我正在回答这个问题:Is there a proper way of resetting a component's initial data in vuejs?

但是,现在不允许使用当前方法,并且 VueJS 禁止更改 $data var。

正如您在https://github.com/vuejs/vue/issues/2873 中看到的那样(不允许修改 $data。)

所以如果我尝试上述方法,我会收到一个 VueJS 警告:

[Vue 警告]:避免替换实例根 $data。使用嵌套数据 属性。

这是我的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!
            }
        }
    }

那么重新初始化我的数据的正确和最简单的方法是什么?

【问题讨论】:

    标签: javascript vue.js vue-component


    【解决方案1】:

    我的解决方案:

    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];});
            }
        }
    }
    

    当您需要时,您可以再次加载或保存它们

    【讨论】:

      【解决方案2】:

      你可以试试这个:

      1. 使用必填字段初始化表单数据属性。 (如第 1 步所示)
      2. 创建另一个数据字段,用于克隆您要重置的表单数据(如步骤 2 中所示)。
      3. 克隆所需的表单数据(步骤 3)
      4. 编写重置方法(步骤 4)
      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();
          },
        },
      };

      【讨论】:

      • 添加一些描述
      【解决方案3】:

      您可以使用Object.assign 遍历所有属性并分配它们:

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

      这是一个演示小提琴:https://jsfiddle.net/797yyvtz/


      注意:我正在使用this.$options.data 再次调用原始data 方法以获取数据的新副本。不需要单独的initialState 函数。 data 方法初始状态函数。

      【讨论】:

      • 注意,此解决方案不会将上下文绑定到data。因此,如果您将 this 用于您的 data 方法,您可能希望将上下文应用于:Object.assign(this.$data, this.$options.data.apply(this))
      • 此解决方案将应用在resetFields() 调用期间可用的组件上下文,因此上下文在此处可用。或者您在谈论在data() 上使用this 是一种不好的做法? (this 是 vue 实例,你可以在这里使用 $store 和其他东西,如果没有 apply(this),这是不可用的)
      • 有什么办法可以去掉重置表单时的验证信息吗?
      【解决方案4】:

      使用称为“数据”或其他东西的键将所有数据包装到字典中。然后可以通过设置 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!
              }
          }
      }
      

      【讨论】:

      • 你读过我上面的问题吗?我无法从你的回答中得出结论。请在发布答案之前仔细阅读问题。
      • @SankalpSingha 是的,我已经仔细阅读了您的问题。我粘贴的代码是嵌套数据属性的方式。代码改动很小,你好像对vue不是很了解,所以没明白。
      • @SankalpSingha 检查这个 jsfiddle 示例,jsfiddle.net/seaify/konv9h78,然后尝试输入并单击重置按钮
      【解决方案5】:

      您是否尝试遍历 initialState 对象并再次设置它?下面是示例代码:

      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];
                  }
              }
          }
      }
      

      在我有限的本地实验中,它似乎确实有效。让我知道您对这种方法的看法。

      【讨论】:

      • 是的,它在我的本地测试中完美运行。但是this[prop] 感觉有点奇怪,因为我们已经习惯在其他任何地方看到this.prop。如果我们赞同“一切都是 javascript 中的对象”的哲学,那么它看起来还不错。
      • 我知道。这是可行的,但对我来说似乎不是最佳解决方案。问题是我在网上找到的所有关于 Vue 的教程都倾向于使用 1.0 或更早版本。在 2.0 中进行了如此多的更改。
      • 我同意。让我们等待一个更好的答案,也许有人可以为我们指出一个同样感觉正确的新方法。即使我对这种方法不满意,我宁愿直接在我的方法中精心重置每个数据属性,而不是盲目地遍历可用的道具并使用奇怪的this[prop] 来设置数据。
      • 如果您也在观看修改模型,这将不起作用。它将触发一个可能不会给模型初始状态的响应
      猜你喜欢
      • 2015-03-16
      • 2016-06-06
      • 2018-12-05
      • 1970-01-01
      • 1970-01-01
      • 2019-10-24
      • 2019-10-03
      • 1970-01-01
      相关资源
      最近更新 更多