【问题标题】:Why Is Vue Data Element Changing When I Only Set It Once?为什么我只设置一次 Vue 数据元素会改变?
【发布时间】:2019-05-31 01:39:41
【问题描述】:

我创建了一个组件,允许用户从列表中选择对象并将它们放入另一个“选定列表”中。因此,主列表中有 100 个项目,而用户选择的列表中有许多项目。他们当然可以根据需要删除和添加项目。

模态框底部有两个按钮。取消并更新。取消忘记了他们添加或删除的任何内容(本质上是他们弹出模式时的撤消),而更新在技术上什么也不做,因为当您添加和删除时,我实际上是在更新真正的选定列表。

所以我的data 有这两个属性(当然还有其他):

originalSelections: [],
selectedMedications: [],

有一种方法只被调用一次到set selectedMedications 属性到originalSelections 的当前状态。我有一个console.log 来证明我没有多次运行此方法并且它永远不会再次受到攻击。

console.log('Post Initing');

let Selected = [];

for (let med of this.value.OtherNotFromEpic) {
  let match = this.otherMedications.find(x => { return x.value === med });

  if (match) {
    Selected.push(JSON.parse(JSON.stringify(match)));
    this.originalSelections.push(JSON.parse(JSON.stringify(match)));
    this.selectedMedications.push(JSON.parse(JSON.stringify(match)));
  }
}

我很困惑为什么 selectedMedications 会发生变化,所以我添加了一个 watch 让我知道是不是这样:

watch: {
  originalSelections(newValue) {
    console.log(' ** Original Selection Changed', this.init, newValue);
  },
},

取消方法如下:

cancel() {
  $('#' + this.modalID).modal('hide');
  console.log('Cancel: this.originalSelections', JSON.parse(JSON.stringify(this.originalSelections)));

  this.selectedMedications = this.originalSelections;

  this.$nextTick(() => {
    console.log('  Cancelled: this.selectedMedications', JSON.parse(JSON.stringify(this.selectedMedications)));
  });
},

您可以看到我将 selectedMedications 设置为原来的值。

奇怪的是......这是我第一次调出模态时 100% 的工作。所以我弹出模式,删除一个项目,取消模式,它会带回我删除的项目。完美!

如果我再次打开模态框,请删除相同的项目或任何其他项目,取消模态框,该项目将保持删除状态,手表实际上已被击中。我在代码中没有其他地方发生过originalMedications = …originalMedications.push 甚至originalMedications.slice。据我了解,我用来设置它的JSON.parse(JSON.stringify(match)) 代码正在创建一个新对象,而不是任何方式的引用。

我发现的另一个奇怪的事情是,如果我刷新页面,打开模式,取消而不做任何添加或删除。然后我再次调出模态并尝试添加或删除,然后取消模态,这些项目不会恢复到originalMedications 状态,因为originalMedicationsselectedMedications 相同。啊!

那么,如果在初始设置之后我从不对其进行任何操作,那么如何更改属性呢?

【问题讨论】:

    标签: vuejs2 vue-component


    【解决方案1】:

    在取消方法中,当两个数据都引用相同(因为它的数组)之后在这里完成下面的直接赋值时。因此,在第一次取消 originalSelections 和 selectedMedications 数组后的任何时候,都会有相同的引用,因此也有相同的数据。

    this.selectedMedications = this.originalSelections;

    而不是更好地使用 concat 如下?这将创建 originalSelections 的副本并将其分配给 selectedMedications。所以对 selectedMedications 的任何操作都不会影响 originalSelections。

    this.selectedMedications = [].concat(this.originalSelections);

    【讨论】:

    • 非常感谢。答案是如此明显。有时您只是太靠近某物而无法看穿代码。太棒了!
    • 我也喜欢较短的版本来获取数组的副本。你知道有没有比let someObject = JSON.parse(JSON.stringify(otherObject));更短的复制对象的方法?
    • 对象复制的简单方法如下,但如果这对您来说不是问题,那么这两种方法都是 ES6 方法。使用传播运算符:let someObject = {...otherObject} 或使用 Object.assign:let someObject = Object.assign({}, otherObject)
    猜你喜欢
    • 1970-01-01
    • 2012-06-13
    • 1970-01-01
    • 1970-01-01
    • 2018-09-13
    • 2021-03-10
    • 1970-01-01
    • 1970-01-01
    • 2019-07-08
    相关资源
    最近更新 更多