Vuex 商店的 Vue.set() 和 push()
Posted
技术标签:
【中文标题】Vuex 商店的 Vue.set() 和 push()【英文标题】:Vue.set() and push() for Vuex store 【发布时间】:2020-04-28 13:59:53 【问题描述】:我有一个尝试进行后续更新的 mutator:
state.forms[1].data.metrics.push(newArrayItem)
forms
是一个以1
为键的对象
metrics
是一个数组
由于某种原因,Vuex 成功更新,但组件没有对此更改做出反应。
我在 https://vuejs.org/v2/guide/list.html#Object-Change-Detection-Caveats 上阅读了有关 Vue.set()
的信息
但我不确定如何应用它,或者即使它在这里完全是正确的答案。
感谢您的帮助。
this.$forceUpdate
正在工作,这有点奇怪,因为加载数据的组件使用了computed
属性。
表单状态最初是这样设置的:
const state =
forms:
;
新表单是这样推送的:
state.forms[id] = formName: payload.formName, data: metrics: [];
新的指标是这样添加的:
var result = getParent(state, payload.path);
result.metricParent.data.metrics.push( id: newMetricId(state, result.formId), ...payload.metric );
【问题讨论】:
你能发布一下状态数据最初是如何设置的吗? 我添加了详细信息。另外,我有一个表单列表,当我在商店中只有一个表单时它起作用了,当事情发生时我添加了“表单”对象。在这里使用动态模块并一次只加载一个表单是一个更好的主意吗? 如果您在任何时候以 Vue 无法观察到的方式改变数据,那么它可能导致不更新视图的突变。见change detection caveats。例如,state.forms[id] = ...
已经是违规行为。
@DecadeMoon 对,我知道,问题是当我需要推送到指标数组时,我不确定如何组合修复(使用 Vue.set 进行数组)通过表单数组访问它。我想我使用动态模块解决了我的问题,但如果你有一个好主意如何组合这些,请告诉我。我什至尝试重新创建数组,推送,然后分配给 state.forms[index],但这也没有用。
【参考方案1】:
您的问题不在于推送到数组。您的问题出在这一行:
state.forms[id] = formName: payload.formName, data: metrics: [];
因为您在没有使用Vue.set()
的情况下创建state.forms
的新属性,所以表单不是反应式的,因此当您稍后推送到指标数组时,它无法识别。
相反,您应该这样做:
Vue.set(state.forms, id, formName: payload.formName, data: metrics: []);
然后,推送到state.forms[id].data.metrics
应该会按预期工作。
【讨论】:
【参考方案2】:Vue 设置响应式数据以查找状态/数据的设置方式,例如,如果在常规组件中定义 x: y: 10
之类的数据并以某种方式更改数据 this.x.y = 20;
它会起作用,因为 Vue 使具有该结构的对象是响应式的(因为是设置结构),如果您尝试这样做,this.x.z = 10;
不起作用,因为“z”不存在,您需要告诉 Vue 您需要使其具有响应性,这是当this.$set(this.x, “z”, 10);
进入时,它基本上是在说“让这个数据在位置'z'反应”,之后直接调用this.x.z = ?
工作,在vuex中也是如此,使用Vue.set(state.forms, 1, formName: payload.formName, data: metrics: []);
之后引用@987654327 @(包括子数据)现在是反应式的!
【讨论】:
当您使用数组并将其设置为初始状态时,每次调用 push 方法都是响应式的,并且不需要手动使用 Vue.set(),在对象中是必要的,因为这是不可能的跟踪 vue 2 中添加的新对象属性以上是关于Vuex 商店的 Vue.set() 和 push()的主要内容,如果未能解决你的问题,请参考以下文章