表格行列拖拽插件

723 阅读1分钟
  • 引入sortablejs 插件

npm install sortablejs --save

  • 引入Vue页面中
<script>
<template>
  <div class="table-view">
      <el-table 
        :data="tableData"
        ...
      >
          <el-table-column
          v-if="order"
          type="index"
          label="序号"
          width="50"
        ></el-table-column>
        ...
      </el-table>
  </div>
</template>
import Sortable from "sortablejs";
export default {
    mounted() {
     //行拖拽
     this.rowDraggy();
     //列拖拽
     this.colDraggy();
  },
  methods:{
    rowDraggy() {
      const tbody = document.querySelector(".el-table__body-wrapper tbody");
      const _this = this;
      Sortable.create(tbody, {
        onEnd({ newIndex, oldIndex }) {
          _this.$emit("rowDraggyEnd", {
            newIndex,
            oldIndex,
          });
        },
      });
    },
    colDraggy() {
      const wrapperTr = document.querySelector(".el-table__header-wrapper tr");
      const _this = this;
      this.sortable = Sortable.create(wrapperTr, {
        animation: 180,
        delay: 0,
        handle: ".allowDrag", // 格式为简单css选择器的字符串,使列表单元中符合选择器的元素成为拖动的手柄,只有按住拖动手柄才能使列表单元进行拖动
        filter: ".noDrag", // 过滤器,不需要进行拖动的元素
        preventOnFilter: true, //  在触发过滤器`filter`的时候调用`event.preventDefault()`
        draggable: ".allowDrag", // 允许拖拽的项目类名
        onEnd: (evt) => {
          _this.$emit("colDraggy", {
            newIndex: evt.newIndex,
            oldIndex: evt.oldIndex,
          });
        },
      });
    },
  }
}
</script>

如上所述,在页面引入sortablejs之后,在页面DOM加载完成之后,挂载行拖拽和列拖拽的监听事件即可,当行列被拖拽之后,触发事件,再对tableData数据进行处理就完成了相应的拖拽操作,再拖拽过程中加上事件防抖以免多次发送请求

  • 实现页面
...
methods: {
    rowDraggyEnd({ newIndex, oldIndex }) {
      let tableDataTemp = _.cloneDeep(this.tableData);
      const currRow = tableDataTemp.splice(oldIndex, 1)[0];
      tableDataTemp.splice(newIndex, 0, currRow);
      this.exchangeTable(tableDataTemp);
    },
    exchangeTable(tableDataTemp) {
      this.tableData = [];
      this.$nextTick(() => {//因为是父子组件传值,所以需要使用这样的赋值方式
        tableDataTemp.forEach((tp) => {
          this.tableData.push(tp);
        });
        this.debounceClick(this.updateBatchPractice, 500);//完成拖拽后,发送请求,
      });
    },
    debounceClick(fun, interval = 200) {
    //事件防抖,以免短时间内多次请求,一定时间内之请求一次
      if (this.timeout) {
        clearTimeout(this.timeout);
        this.timeout = null;
      }
      this.timeout = setTimeout(() => {
        fun();
      }, interval);
    },
 },
 updateBatchPractice() {
      console.log(" this.tableData", this.tableData);
      let params = {
        practicePvos: [],
      };
      this.tableData.forEach((t, i) => {
        params.practicePvos.push({
          capabilityLevelId: t.capabilityLevelId,
          practiceFieldId: t.practiceFieldId,
          practiceId: t.practiceId,
          practiceIdentification: t.practiceIdentification,
          practiceName: t.practiceName,
          sort: i,
        });
      });
      sysDocManage
        .updateBatchPractice(params)
        .then((res) => {
          let { code, message } = res;
          if (code !== 200) {
            this.$message.error(message);
          }
        })
        .catch((err) => {
          console.log(err);
        });
    }
 }