重置reactive对象(深拷贝与浅拷贝)

需求,点击不同登录方式,该图标高亮,别的图标置灰。(高亮和置灰都有相应的引入图片)

<div class="other_icon">
 <img @click="changeLoginType(item.index)" v-for="item in imgAddress" :src="item.photo" :key="item.index" />
</div>


let imgAddress = reactive([
  { photo: oneClickLoginIcon, index: 0 },
  { photo: passwordLoginIcon, index: 1 },
  { photo: phoneLoginIcon, index: 2 },
  { photo: simCardLoginIcon, index: 3 }
])

//备份
let imgAddressCopy = reactive([])
onMounted(() => {
    imgAddressCopy.push(...imgAddress) //获得备份数组
})
//重置imgAddress数组
function resetImgAddress() {
  imgAddress.length = 0
  imgAddress.push(...imgAddressCopy)
}
/**
 * 切换登录方式时图标更改
 * @param index 图标索引
 */
function changeLoginType(index) {
  resetImgAddress()
//点击不同的index,图标改变
  switch (index) {
    case 0:
      imgAddress[0].photo = oneClickLoginIconAct
      break
    case 1:
      imgAddress[1].photo = passwordLoginIconAct
      break
    case 2:
      imgAddress[2].photo = phoneLoginIconAct
      break
    case 3:
      imgAddress[3].photo = simCardLoginIconAct
      break
  }
}

此时发现点击不同的index,仍然会保留上一次的更改。

原因:

在 JavaScript 中,数组是引用类型,所以当你将 imgAddress 数组中的对象 push 到 imgAddressCopy 数组中时,实际上是将对象的引用 push 到了 imgAddressCopy 中,而不是对象的拷贝。因此,当你改变 imgAddress 数组中对象的属性时,实际上也改变了 imgAddressCopy 中对应对象的属性,因为它们引用的是同一个对象。

解决这个问题的方法是在 push 对象到 imgAddressCopy 数组中时,不要直接 push 引用,而是创建一个新的对象,以确保两个数组中的对象是独立的。这样,当你改变 imgAddress 数组中对象的属性时,不会影响 imgAddressCopy 数组中对象的属性。

let imgAddress = reactive([
  { photo: oneClickLoginIcon, index: 0 },
  { photo: passwordLoginIcon, index: 1 },
  { photo: phoneLoginIcon, index: 2 },
  { photo: simCardLoginIcon, index: 3 }
])
// 初始状态
let imgAddressCopy = reactive([])

onMounted(() => {
  //获得备份数组
  imgAddressCopy.push(...imgAddress.map(obj => ({ ...obj })))
})

function resetImgAddress() {
  imgAddress.length = 0
  imgAddress.push(...imgAddressCopy.map(obj => ({ ...obj })))
}
/**
 * 切换登录方式时图标更改
 * @param index 图标索引
 */
function changeLoginType(index) {
  resetImgAddress()
  switch (index) {
    case 0:
      imgAddress[0].photo = oneClickLoginIconAct
      break
    case 1:
      imgAddress[1].photo = passwordLoginIconAct
      break
    case 2:
      imgAddress[2].photo = phoneLoginIconAct
      break
    case 3:
      imgAddress[3].photo = simCardLoginIconAct
      break
  }
}

在Vue 3中重置reactive数据的最佳方法是使用Object.assign()函数。你可以创建一个函数来获取初始状态的数据,并将其与reactive对象进行合并。例如,你可以使用以下代码来重置reactive数据: ```javascript const getInitialState = () => { return { a: 1 }; }; const state = reactive(getInitialState()); const resetState = () => { Object.assign(state, getInitialState()); }; ``` 这样,当你调用resetState函数时,reactive数据将被重置为初始状态。\[2\]你可以根据自己的需求修改getInitialState函数来返回你想要的初始数据。 另外,如果你有一个名为info的reactive数据对象,你可以使用以下代码来重置它的值: ```javascript const info = reactive<{ name: string; age: string; gender: string }>({ name: "1", age: "2", gender: "3", }); // 重置info的值 info.name = "初始值"; info.age = "初始值"; info.gender = "初始值"; ``` 通过将每个属性的值设置为初始值,你可以重置reactive对象的值。\[3\]请注意,这种方法只适用于简单的对象,如果你的reactive数据对象更复杂,请使用Object.assign()函数来进行重置。 希望这些信息对你有帮助! #### 引用[.reference_title] - *1* *2* [Vue3 - 如何将 reactive() 创建的响应式数据 “轻松“ 恢复成初始数据值,重置 reactive() 定义的数据使其...](https://blog.csdn.net/weixin_44198965/article/details/129285200)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [vue3 关于reactive重置问题](https://blog.csdn.net/ViFong/article/details/123474716)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值