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;  // 添加整个盒子高亮
}