Loading

实现表格行列拖拽-【sortablejs】

背景

有的时候我们需要前端来实现行和列的拖拽,把想要看的内容往前提,

效果图

代码

  1. 为el-table设置row-key ,如不设置会导致拖拽顺序紊乱
  2. 行拖拽,通过获取拖拽前后移动行的索引,更新表格数据
  3. 列拖拽,注意:这块需要多写一个列数组!---这块不是很懂为什么,但是如果不增加列数组去操作的话是达不到列拖拽的效果
<template>
  <div class="app">
    <h1>实现表格行列拖拽</h1>
    <el-table
      class="drag-table"
      row-key="id"
      :data="tableData"
      border
      style="width: 100%"
    >
      <el-table-column
        v-for="(item, index) in columns"
        :key="item.prop"
        :prop="dragCols[index].prop"
        :label="item.label"
      ></el-table-column>
    </el-table>

    <div class="data-box">
      <pre>
        <h3>columns</h3>
        {{ columns }}
      </pre>
      <hr />
      <pre>
        <h3>dragCols</h3>
        {{ dragCols }}
      </pre>
    </div>
  </div>
</template>

<script setup>
import { onMounted, ref } from "vue";
import Sortable from "sortablejs";
import Mock from "mockjs";

// 模拟表格数据
const tableData = ref([]);
const ret = Mock.mock({
  "result|10-20": [
    {
      id: "@guid",
      "number|+1": 1,
      date: "@date",
      name: "@name",
      email: "@email",
      address: "@csentence(8,15)",
    },
  ],
});
tableData.value = ret.result;

onMounted(() => {
  setRowDrag();
  setColDrag();
});

// 1. 设置行拖拽
const setRowDrag = () => {
  // 1.1 获取tbody元素
  const tbody = document.querySelector(".drag-table .el-table__body tbody");
  Sortable.create(tbody, {
    onEnd: ({ newIndex, oldIndex }) => {
      // 1.2 获取拖拽前后的索引,然后更新表格数据
      const currentRow = tableData.value.splice(oldIndex, 1)[0];
      tableData.value.splice(newIndex, 0, currentRow);
    },
  });
};

const columns = ref([
  {
    label: "序号1",
    prop: "number",
  },
  {
    label: "日期2",
    prop: "date",
  },
  {
    label: "姓名3",
    prop: "name",
  },
  {
    label: "邮件4",
    prop: "email",
  },
  {
    label: "地址4",
    prop: "address",
  },
]);
const dragCols = ref([
  {
    label: "序号1",
    prop: "number",
  },
  {
    label: "日期2",
    prop: "date",
  },
  {
    label: "姓名3",
    prop: "name",
  },
  {
    label: "邮件4",
    prop: "email",
  },
  {
    label: "地址4",
    prop: "address",
  },
]);
// 2. 设置列拖拽
const setColDrag = () => {
  // 2.1 获取元素
  const tr = document.querySelector(".drag-table .el-table__header-wrapper tr");
  Sortable.create(tr, {
    animation: 180,
    delay: 0,
    onEnd: (e) => {
      // 注意:这里需要定义对一个相同的列
      const oldColumn = dragCols.value[e.oldIndex];
      dragCols.value.splice(e.oldIndex, 1);
      dragCols.value.splice(e.newIndex, 0, oldColumn);
    },
  });
};
</script>

<style lang="less" scoped>
.data-box {
  position: fixed;
  right: 0;
  top: 0;
  width: 500px;
  background-color: orange;
  h3 {
    text-align: center;
  }
}
</style>
posted @ 2023-09-07 08:14  ^Mao^  阅读(598)  评论(0编辑  收藏  举报