Vue computed属性过滤销售代理时意外修改store state问题排查
问题根源
核心问题是JS引用类型数据的共享特性导致的原始数据被篡改:
- 第一步筛选仓库时,你直接把从state获取的原始仓库对象
push到了computedWarehouses数组中。JS中对象是引用类型,此时computedWarehouses里的仓库对象和state里的原始仓库对象指向同一块内存地址,修改任意一方都会同步影响另一方。 - 后续你给
computedWarehouses[warehouse].period.workdaysObjects[workday].salesAgents赋值新数组的操作,本质上就是直接修改了state里的原始数据,所以才会出现取消勾选后原始数据丢失、重新勾选无法恢复的问题。
修复方案
筛选时对需要修改嵌套属性的对象做逐层浅拷贝,所有修改都作用在新生成的拷贝对象上,完全不触及原始state数据:
computedWarehouses() { const intWarehousesFilter = this.warehousesFilter.map(id => parseInt(id)); const intConsultantsFilter = this.consultantsFilter.map(id => parseInt(id)); // 先筛选符合条件的仓库,再逐层拷贝对象做销售代理筛选 return this.data .filter(warehouse => intWarehousesFilter.includes(warehouse.id)) .map(warehouse => ({ // 浅拷贝仓库根属性 ...warehouse, period: { // 浅拷贝period属性 ...warehouse.period, // 遍历工作日数组,对每个工作日做拷贝 workdaysObjects: warehouse.period.workdaysObjects.map(workday => ({ ...workday, // 直接返回筛选后的销售代理数组,所有修改都在新拷贝对象上生效 salesAgents: workday.salesAgents.filter(agent => intConsultantsFilter.includes(parseInt(agent.id)) ) })) } })) }
逻辑说明
- 用扩展运算符
...逐层拷贝需要修改的嵌套对象,和原始state数据完全切断引用关联 - 用原生数组的
filter+map简化逻辑,可读性和运行效率都更高 - 原始state的
data全程不会被修改,重新勾选筛选条件时计算属性可以正常从原始数据生成完整的筛选结果
内容的提问来源于stack exchange,提问作者MarkusV
相关产品推荐
相关产品推荐

