基于el-table封装的一个可拖动行组件

75 阅读1分钟

查了半天资料不一不是用Sortablejs、vueUse下的useDraggable、vuedraggable,也看了使用js自己实现的方式,但感觉无一不是晦涩难懂就是太复杂,急的我自己写了一个,发现其实如此简单,本质还是利用了vue的响应式原理实现

上代码,copy下来好好看看其实一点都不难
<template>
  <div>
    <el-table :data="tableData">
      <el-table-column draggable="" prop="date" label="Date" width="180" />
      <el-table-column prop="name" label="Name" width="180" />
      <el-table-column prop="address" label="Address" />
    </el-table>
  </div>
</template>

<script lang="ts" setup>
import { onMounted, ref } from "vue";

const tableData = ref([
  {
    date: "2016-05-03",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-02",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-04",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
  {
    date: "2016-05-01",
    name: "Tom",
    address: "No. 189, Grove St, Los Angeles",
  },
]);
const dragIndex = ref();

onMounted(() => {
  const row = document.querySelectorAll(".el-scrollbar tbody .el-table__row") as NodeListOf<HTMLTableRowElement>;
  row.forEach((li: HTMLTableRowElement, index) => {
    li.setAttribute("draggable", "true");
    li.setAttribute("key", index.toString());
    // li.getAttribute
    li.ondragstart = (e) => {
      dragIndex.value = (e.srcElement as HTMLElement).getAttribute("key") as string;
    };
    li.ondragenter = (e) => {
      e.preventDefault();
      const _currentIndex = (e.srcElement as HTMLElement).getAttribute("key") as string;
      if (dragIndex.value !== _currentIndex) {
        const source = tableData.value[dragIndex.value];
        tableData.value.splice(dragIndex.value, 1);
        tableData.value.splice(index, 0, source);
        dragIndex.value = index;
      }
    };

    li.ondragover = (e) => {
      e.preventDefault();
    };
  });
});
</script>