Notion Blog
知行合一1 分钟阅读

分享一个实现 antd3.0 a-table 拖动排序的 Vue3 代码示例

Ant Design Vue 3.0 的 a-table 组件在Pro版本中提供了拖动排序的功能,但是在免费版中并未包含。不过a-table 提供了 customRow 属性,通过这个入口我们可以自己实现拖动排序。下面我会分享具体的代码实现。

代码示例

<template>
  <a-table 
    :data-source="tableData"
    :custom-row="customRow"
    <template #bodyCell="{column, text}">
      ...
    </template>

  </a-table>
</template>
<script>

export default defineComponent({
const tableData= reactive([
      { name: "John", id: 1 },
      { name: "Joao", id: 2 },
      { name: "Jean", id: 3 },
      { name: "Gerard", id: 4 },
    ]);
let change1;
    function customRow(record, index) {
      let change2;
      return {
        props: {
          // draggable: 'true'
        },
        style: {
          cursor: "pointer",
        },
        // 鼠标移入
        onMouseenter: (event) => {
          // 兼容IE
          var ev = event || window.event;
          ev.target.draggable = true; // 让你要拖动的行可以拖动,默认不可以
        },
        // 开始拖拽

        onDragstart: (event) => {
          // 兼容IE
          var ev = event || window.event;
          // 阻止冒泡
          ev.stopPropagation();
          // 得到源目标数据序号
          change1 = index;
        },
        // 拖动元素经过的元素
        onDragover: (event) => {
          // 兼容 IE
          var ev = event || window.event;
          // 阻止默认行为
          ev.preventDefault();
        },
        // 鼠标松开
        onDrop: (event) => {
          // 兼容IE
          var ev = event || window.event;
          // 阻止冒泡
          ev.stopPropagation();
          // 得到目标数据序号
          change2 = index;
          // // 让视图更新 
          if (change1 < change2) {
            const startObj = tableData[change1];
            tableData.splice(change2 + 1, 0, startObj);
            tableData.splice(change1, 1);
          } else if (change1 > change2) {
            const startObj = tableData[change1];
            tableData.splice(change2, 0, startObj);
            tableData.splice(change1 + 1, 1);
          }
        },
      };
    }
return {
customRow,
tableData
}

})

</script>

使用 customRow 处理拖放事件

要实现拖动排序,首先需要通过 customRow 为每一行添加拖放事件的处理:

function customRow(record, index) {

  return {
    onDragstart(e) {
      // 保存当前拖动项和索引 
    },
    
    onDragover(e) {
      e.preventDefault()
    },
    
    onDrop(e) {
      // 获取目标索引
      // 交换两项位置
    }
  }
}

在拖动开始保存当前项和索引,拖动经过阻止默认事件,最后在拖动结束时交换两个索引位置上的项,这样就可以改变顺序。

处理数据和更新视图

然后需要在数据层面上交换顺序,并触发视图更新:

 onDrop: (event) => {
          // 兼容IE
          var ev = event || window.event;
          // 阻止冒泡
          ev.stopPropagation();
          // 得到目标数据序号
          change2 = index;
          // // 让视图更新 
          if (change1 < change2) {
            const startObj = tableData[change1];
            tableData.splice(change2 + 1, 0, startObj);
            tableData.splice(change1, 1);
          } else if (change1 > change2) {
            const startObj = tableData[change1];
            tableData.splice(change2, 0, startObj);
            tableData.splice(change1 + 1, 1);
          }
        },

直接修改数组会导致视图不更新,需要生成一个新数组来触发响应式。

有关使用上的问题,欢迎您在底部评论区留言,一起交流~

读者评论

评论会同步写入该文在 Notion 中的页面底部(与正文同页,便于管理)。

0/1500

暂无评论,欢迎抢沙发。