You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue问题:向含数组的对象添加元素时所有数组均被更新

问题:调用addBatch时所有item的batches数组都被同步更新

我声明了如下的items对象:

const newItem = {itemId: '', price: '0.00', discount: 0, discountedPrice: 0, batches: [2]}
const items = ref([{...newItem, ...{id: 0}}])

我希望能向batches键中添加新成员,写了以下方法:

const addItem = () => {
    items.value.push({...newItem, ...{id: items.value.length}})
}

const addBatch = (batches) => {
    console.log(batches)
    batches.push(0)
}

但当我在模板中调用addBatch时,所有item的batches都被更新了:

<tr v-for="(item, index) in items" :key="item.id" class="bg-slate-200">
  <td class="p-1 text-center align-top">
    <input :name="'itemId[' + index + ']'"
      type="text"
      placeholder="Item..."
      v-model="item.itemId"
      class="rounded border border-gray-500 text-gray-900 p-1 w-full text-xs min-w-[100px]"
    />
  </td>
  <td class="p-1 text-center align-top">
    <div class="grid grid-cols-2">
      <div>
        <input v-for="(batch, batchIndex) in item.batches"
          :key="batchIndex + 'batch'"
          :name="'quantity[' + index + '][]'"
          :value="batch"
          type="number"
          placeholder="Quantity..."
          min=".001"
          max="1000000000"
          step=".001"
          class="rounded border border-gray-500 text-gray-900 p-1 text-xs w-full"
        />
      </div>
      <div>
        <button @click="addBatch(item.batches)"
          type="button"
          class="text-xs bg-green-600 flex p-1 items-center rounded text-white ml-1"
        ></button>
      </div>
    </div>
  </td>
</tr>

我尝试了各种方法,但始终无法理解为何所有batches都会被更新,而不是仅更新传入函数的那一个?


原因分析

问题出在对象浅拷贝上:你用{...newItem}展开对象时,对于batches这种数组类型的属性,只会拷贝它的内存引用,不会创建新的数组实例。这就导致所有通过addItem添加的item,它们的batches都指向同一个数组。所以你调用batches.push(0)时,所有item都会同步看到这个数组的变化。

解决方案

创建新item时,要对batches做独立拷贝,确保每个item的batches都是专属的数组。有两种修改方式:

方式一:封装创建新item的函数

每次创建都生成全新的数组:

const createNewItem = (id) => {
  return {
    itemId: '',
    price: '0.00',
    discount: 0,
    discountedPrice: 0,
    batches: [2], // 每次创建新数组
    id: id
  }
}

const items = ref([createNewItem(0)])

const addItem = () => {
    items.value.push(createNewItem(items.value.length))
}

const addBatch = (batches) => {
    batches.push(0)
}

方式二:保留原newItem,拷贝时手动克隆batches

在展开对象时单独复制数组:

const newItem = {itemId: '', price: '0.00', discount: 0, discountedPrice: 0, batches: [2]}

const items = ref([{...newItem, batches: [...newItem.batches], id: 0}])

const addItem = () => {
    items.value.push({
        ...newItem,
        batches: [...newItem.batches], // 克隆数组,生成新引用
        id: items.value.length
    })
}

这样每个item的batches都是独立的数组,调用addBatch时只会修改当前点击的item对应的数组,不会影响其他item。

内容的提问来源于stack exchange,提问作者user5318896

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.19 17:13:10