需求:点击全选按钮,本页所有勾选框都选中,(即将pagePhoneId赋值给selectedIds)
这两个变量的数据结构一模一样,类似['11111','33333','555555'],里面存着id
let selectedIds=ref([]) //勾选的id数据,是变化的
let pagePhoneId=ref([]) //后端接口获得的本页id数据,在同一页中,是一直固定的
//.......省略其余的逻辑//监听全选
onSelectPhonesAllGroup(groupId => {let targetGroup = deviceList.value.find(group => {return group.groupId === groupId})if (targetGroup) {// 当前分组下的云机id若属于本页则全部选中,不支持跨页全选targetGroup.group.forEach(item => {if (pagePhoneId.value.includes(item.phoneId)) {item.isChecked = true}})selectedIds.value = pagePhoneId.value //勾选全部的数据sessionStorage.setItem('leftSelectedIds', JSON.stringify(selectedIds.value))sessionStorage.setItem('rightSelectedIds', JSON.stringify(selectedIds.value))checkGroupAllOrIndeterminateSelected(targetGroup)}
})
按上述代码,发现selectedIds.value的变化会影响pagePhoneId.value,但是明明pagePhoneId.value应该是一个固定的数值(从后端接口那里拿到的)
原因:赋值方法错误
selectedIds.value = pagePhoneId.value
这种方法直接将
pagePhoneId.value
的引用赋值给selectedIds.value
。这意味着selectedIds.value
和pagePhoneId.value
实际上指向的是同一个对象(或数组)。因此,对selectedIds.value
的任何修改都会直接影响到pagePhoneId.value
,因为它们是同一个数据的两个引用。
修改成:selectedIds.value = JSON.parse(JSON.stringify(pagePhoneId.value))
这种方法通过
JSON.stringify
将pagePhoneId.value
转换成一个JSON字符串,然后再通过JSON.parse
将这个字符串转换回一个对象(或数组),并赋值给selectedIds.value
。这是一个深拷贝的过程,意味着selectedIds.value
和pagePhoneId.value
在内存中是两个完全不同的对象(或数组),它们之间没有任何引用关系。因此,对selectedIds.value
的修改不会影响pagePhoneId.value
。
结论:
- 当你希望两个变量始终指向同一个数据,并且对一个变量的修改应该反映到另一个变量上时,你应该使用直接引用赋值。
- 当你希望两个变量各自拥有独立的数据副本,并且对一个变量的修改不应该影响另一个变量时,你应该使用深拷贝赋值(或者其他形式的深拷贝方法)