antd vue table表格实现拖拽排序
遇到的问题
antd vue table 默认是不支持表格拖拽排序的,但在实际的使用中,是有拖拽排序的需求。
解决方案
为此,官网文档提供了一个API customRow,用来设置行属性。
实现步骤
- 首先在table上添加属性
<a-table :columns="columns" :data-source="table.list" :custom-row="customRow">
...
</a-table>
- 然后定义该方法,设置高亮等
// 定义基础数据源
const table = {
list: [], // 数据列表
sourceCode: '', // 源目标code
targetCode: '', // 目标code
}
// 设置行属性方法
const customRow = (record: any, index: number) => {
console.log('customRow', record, index)
return {
props: {
// draggable: 'true'
},
style: {
cursor: 'pointer',
},
// 鼠标移入
onMouseenter: (event: any) => {
const ev = event || window.event // 兼容IE
ev.target.draggable = true // 让你要拖动的行可以拖动,默认不可以
},
// 开始拖拽
onDragstart: (event: any) => {
const ev = event || window.event // 兼容IE
ev.stopPropagation() // 阻止冒泡
// 得到源目标数据序号
table.sourceCode = record.sourceCode
console.log('sourceCode', table.sourceCode)
},
// 拖动元素经过的元素
onDragover: (event: any) => {
// 兼容 IE
const ev = event || window.event
// 阻止默认行为
ev.preventDefault()
},
// 拖动到达目标元素
onDragenter: (event: any) => {
const ev = event || window.event
ev.preventDefault()
// 设置拖动高亮效果
const list = document.getElementsByClassName('ant-table-row')
const node = document.getElementsByClassName('target')
if (node.length) {
node[0].classList.remove('target')
}
list[index].classList.add('target')
},
// 鼠标松开
onDrop: (event: any) => {
const ev = event || window.event // 兼容IE
ev.stopPropagation() // 阻止冒泡
// 得到目标数据序号
table.targetCode = record.targetCode
console.log('targetCode', table.targetCode)
// 取消高亮效果
const node = document.getElementsByClassName('target')
if (node.length) {
node[0].classList.remove('target')
}
// 在备份数组上执行排序操作
const list = table.list.slice()
// 1. 通过code找到拖拽起始数据,备份它,并从数组中删除
const sourceIndex = list.findIndex((item) => item.sourceCode === table.sourceCode)
const sourceItem = list[sourceIndex]
list.splice(sourceIndex, 1)
// 2. 通过code找到拖拽终点index,把备份的起始数据插入这个位置
const targetIndex = list.findIndex((item) => item.targetCode === table.targetCode)
const targetItem = list[targetIndex]
if (sourceIndex === targetIndex) {
list.splice(targetIndex + 1, 0, sourceItem)
} else {
list.splice(targetIndex, 0, sourceItem)
}
// 排序好的数组应用到响应式数据中
table.list = list
},
}
}
// 添加高亮样式
:deep(.ant-table-tbody > tr.target > td) {
border-top: 1px solid #409eff; // 添加上边框
// background-color: #d9ecff; // 添加整个盒子高亮
}