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

Vue3 Composition API中向数组推入对象时数据被覆盖的问题排查

为什么添加第二个选择项时已添加的第一个会被覆盖?

问题场景

我做了一个包含两个选择项的功能:

  • size选项:可选large、small(代码里实际用了Standart、Big)
  • quantity选项:可选2/4/6(代码里实际用了6、8、12)
    选中选项后头部会展示所选内容,点击「add to storage」按钮把数据存入存储,之后在另一页面展示列表。

我的尝试代码:

Vue TS 逻辑代码

const chosenMachines = reactive([]);

const machineInfo = ref({
 size: "Standart",
 glasses: 6
})

const addToList = () => {
 // myStore.addToStoredItems(machineInfo)  ---> 计划用Pinia存储
 chosenMachines.push(machineInfo.value)
}

模板代码

<div>Title {{ machineInfo.size  }} | {{ machineInfo.glasses }}</div>        
  <select name="size" v-model='machineInfo.size'  class='selects__select-item'>
    <option>Standart</option>
    <option>Big</option>
  </select>
  <select name="glasses" v-model.number='machineInfo.glasses' class='selects__select-item'>
    <option>6</option>
    <option>8</option>
    <option>12</option>
  </select>
 <button class='btn' @click='sendToStorage'>Add</button>

现在遇到的问题:添加第一个对象后,再选新的选项添加第二个,第一个对象的内容会被改成新选项的值,看起来像是被覆盖了。

原因分析

核心问题是对象引用共享:

  • machineInfo.value是一个固定的对象,你每次调用addToList时,都是把这个对象的引用push到chosenMachines数组里。
  • 数组里的所有元素其实都指向同一个内存地址的对象,当你通过select修改machineInfo.value的属性时,数组里所有引用这个对象的元素都会同步变化,导致之前添加的项看起来被覆盖了。

另外还有一个小问题:模板里按钮的点击事件是sendToStorage,但逻辑里定义的方法是addToList,这会导致点击按钮没有反应,需要统一方法名。

解决方案

每次添加时,创建一个当前machineInfo.value的对象副本,把副本push到数组里,这样每个元素都是独立的对象,不会互相影响。

修改后的addToList方法:

const addToList = () => {
 // 用扩展运算符创建对象副本
 chosenMachines.push({...machineInfo.value})
 // 也可以用Object.assign实现:Object.assign({}, machineInfo.value)
 // 如果用Pinia存储,同样要存副本:myStore.addToStoredItems({...machineInfo.value})
}

同时修正模板里的按钮点击事件:

<button class='btn' @click='addToList'>Add</button>

这样每次添加的都是独立的对象,后续修改select的值只会影响当前的machineInfo,不会改变数组里已有的项。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 18:55:05