微信小程序setData深浅拷贝

你这是“引用”在作怪。

MultiChange 里你写了:

this.setData({
  multiArray_show: this.data.multiArray,
  multiIndex_show: this.data.multiIndex
});

multiArraymultiIndex 都是引用类型(数组/对象)。上面这段并不是拷贝数据,而是把 *_show 指向了同一块内存。随后在 MultiColumnChange 里你又做了:

let { multiArray, multiIndex } = this.data;
multiIndex[column] = value;   // 直接原地改
...
this.setData({ multiArray, multiIndex });

由于 multiIndex_showmultiIndex 指向的是同一个数组,任何一方的原地修改都会互相“联动”,于是两个 console.log 看起来一样。


正确做法:拷贝一份再改

**方案 A(推荐):在赋给 _show 时做深/浅拷贝*

MultiChange(e) {
  this.setData({
    // multiArray 是二维数组,需要“逐列”拷贝,避免共享子数组
    multiArray_show: this.data.multiArray.map(col => col.slice()),
    // multiIndex 是一维数组,浅拷贝即可
    multiIndex_show: this.data.multiIndex.slice(),
  });
  this.getWeekInfo();
}

方案 B:在修改前先拷贝再改

MultiColumnChange(e) {
  const { column, value } = e.detail;

  // 拷贝出“新数组”再改,避免原地改 this.data 里的引用
  const multiIndex = this.data.multiIndex.slice();
  const multiArray = this.data.multiArray.map(col => col.slice());

  multiIndex[column] = value;

  if (column === 0) {
    multiArray[1] = value === 0
      ? ["电子楼302", "电子楼306", "电子楼309"]
      : ["图书馆304", "图书馆426", "图书馆516", "图书馆301"];
    multiIndex[1] = 0;
  }

  this.setData({ multiArray, multiIndex });

  console.log(this.data.multiIndex);
  console.log(this.data.multiIndex_show);
}

方案 C:用 structuredClone 或 JSON 深拷贝

this.setData({
  multiArray_show: structuredClone(this.data.multiArray), // 若运行环境支持
  multiIndex_show: [...this.data.multiIndex],
});

// 或者
this.setData({
  multiArray_show: JSON.parse(JSON.stringify(this.data.multiArray)),
  multiIndex_show: [...this.data.multiIndex],
});

小贴士:

  • 避免直接原地改 this.data.xxx[i] = ... 这种写法;要么先克隆再改,要么用 setData 的路径更新(如 "multiIndex[1]": 0)。
  • multiArray 是二维数组,必须深一点的拷贝(至少把每一列 slice 一遍),否则子数组还会共享引用。

按上面的任一方案改完,你再 console.log,两个值就不会“黏在一起”了。接下来你可以把同样的拷贝思路应用到其他需要显示/确认用的数据镜像上,避免“联动修改”的坑。

posted @ 2025-08-31 00:31  saulstavo  阅读(12)  评论(0)    收藏  举报