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

Posted

技术标签:

【中文标题】在 VueJs 2.0 中重新初始化数据的正确方法【英文标题】:Proper way to re-initialize the data in 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!
            
        
    

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

【问题讨论】:

【参考方案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 步所示) 创建另一个数据字段,用于克隆您要重置的表单数据(如步骤 2 中所示)。 克隆所需的表单数据(步骤 3) 编写重置方法(步骤 4) 在您喜欢的任何地方使用(第 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] 来设置数据。 如果您也在观看修改模型,这将不起作用。它将触发一个可能不会给模型初始状态的响应

以上是关于在 VueJs 2.0 中重新初始化数据的正确方法的主要内容,如果未能解决你的问题,请参考以下文章

如何在 React Apollo 2.0 中正确地重新获取和缓存更新的数据?

vuejs 从子组件更新父数据

vuejs 从子组件更新父数据

created() 或计算属性中的 vuejs 初始化数据函数(方法)

VueJS 2.0 从父级到子级的通信

数据绑定整个页面的正确方法或vuejs方法是啥?