需求
拖拽表格的行数据,实现排序。
问题
拖拽后调用接口,但视图没变,还是原来的顺序
场景:拖拽表格行数据后,tableDataArr
中数据的 orderNum
值会改变,实现拖拽换序。
期望情况:页面根据更改后的 orderNum
重新排序。
实际情况:接口数据变了,但是页面行数据没有改变。也就是说,页面没有实现响应式更新。
尝试1:使用 $set
赋值,无效。
// 旧代码:
this.tableDataArr = arr.slice(
(this.pageNum - 1) * this.pageSize,
this.pageNum * this.pageSize
);
// 新代码:无效
this.$set(this, 'tableDataArr', arr.slice(
(this.pageNum - 1) * this.pageSize,
this.pageNum * this.pageSize
))
尝试2:赋值后使用 this.$forceUpdate()
强制更新,无效
尝试3:使用 splice()
赋值
const newArr = arr.slice((this.pageNum - 1) * this.pageSize,this.pageNum * this.pageSize)
this.tableList.splice(
0,
this.tableList.length,
...newArr
);
解决:赋值前先重置数组
// 重置 tableList,避免换序不更新页面
this.tableList = [];
// 赋值
this.tableDataArr = arr.slice(
(this.pageNum - 1) * this.pageSize,
this.pageNum * this.pageSize
);
原因
sortable.js
拖拽排序是插入,即把A插入到B之前或之后。拖拽(页面数据顺序改变了但数组没变)后,再调用换序接口,获得的数组变了,但没有引起视图的变化。
这是因为 Vue 无法监听数组顺序的改变。
拖拽方向不同,导致被替换行不同(测试需从不同拖拽方向测试)
- 拖拽行 A
- 插入行 B
- 被替换行
备注:oldIndex 指的是 A 原来的位置,newIndex 指的是 A 拖拽后的位置。
情况一:oldIndex < newIndex
- A 拖到B 后面,A 取代了 B 原来的位置;
- A 拖到B 前面,A 取代了 B 前一个属性,即C 原来的位置;
情况二:oldIndex > newIndex
- A 拖到B 后面,A 取代了 B 后一个属性,即C 原来的位置;
- A 拖到B 前面,A 取代了 B 原来的位置;
如何修改放置行的背景色
ghostClass
属性:颜色名。若为空字符串表示无颜色。
如何限制可拖拽的区域、可放置区域
filter
属性:可拖拽的元素
onMove
限制可放置区域
Sortable.create(tbody, {
filter: ".common-row", // 继承属性不可拖拽
……
// 不允许拖拽到继承属性区域中
onMove(e) {
return e.related.className.indexOf("common-row") === -1;
},
});