在 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 中正确地重新获取和缓存更新的数据?