当进行上移/下移操作时,`el-tree-select` 的数据更新错位,比如修改第一行实际更新了第二行的数据。

104 阅读1分钟

问题原因

  1. Vue的数据绑定机制:
  • 使用 v-model 时,Vue会维护一个响应式引用

  • 当数组元素位置交换时,引用关系可能没有正确更新

2.数组交换的特殊性: [list[indexA], list[indexB]] = [list[indexB], list[indexA]];

这种交换方式可能导致对象引用没有完全分离 3.el-tree-select的绑定方式: <el-tree-select v-model.number="scope.row.feeSeqNo" @change="(e) => onchangetreedata(e,scope.row,scope.$index)" />

  • 这种绑定方式依赖于 scope.row 的引用,当位置交换时可能保持了原有的引用关系

解决方案

1 使用显式的值绑定: <el-tree-select :model-value="scope.row.feeSeqNo" @update:model-value="(val) => handleTreeSelectChange(val, scope.row, scope.$index)" /> 2. 确保数据更新到正确的索引位置:  const handleTreeSelectChange = (value, row, index) => { state.tableForm.tableData[index] = { ...state.tableForm.tableData[index], feeSeqNo: value }; }

  1. 移动时创建新的对象引用
const temp = { ...list[indexA] };
list[indexA] = { ...list[indexB] };
list[indexB] = { ...temp };

为什么这样解决有效

  • 显式的值绑定确保了数据流向的清晰性

  • 通过索引直接更新数组确保了数据更新到正确的位置

  • 创建新的对象引用避免了共享引用导致的问题

经验总结

  • 当处理复杂的数组操作时,需要特别注意对象引用的问题

  • 使用显式的数据流向可以帮助避免一些隐含的绑定问题

  • 在移动数组元素时,最好创建新的对象引用而不是直接交换

这个问题本质上是 Vue 的响应式系统和数组操作之间的交互导致的,通过更明确的数据流向和引用管理解决了问题。