在表格里面进行拖拽,肯定没法用组件的形式,因为会破坏table的结构,所以只能从 dom上入手。

安装插件

yarn add sortablejs  --dev

中文说明站点:sortablejs中文网

使用

<template>
  <el-table :data="tbody" id="appTable" row-key="id">
    ...
  </el-table>
</template>
<script>
import Sortable from "sortablejs/modular/sortable.core.esm.js";
export default {
  data(){
    return {
      tbody:[]; //表格数据
    }
  },
  methods: {
    //初始化拖拽表格
    initSortable() {
      this.$nextTick(() => {
        const appTable = document.querySelector(
          "#appTable .el-table__body>tbody"
        );
        this.$appTable = Sortable.create(appTable, {
          animation: 150,
          ghostClass: "sortable-ghost",
          onEnd: (event) => {
            const oldItem = this.tbody[event.oldIndex];
            this.tbody.splice(event.oldIndex, 1);
            this.tbody.splice(event.newIndex, 0, oldItem);
            //保存拖拽排序api
            //自己写业务请求,idArr得到了拖拽后的数组id顺序
            //const idArr = this.tbody.map((item) => item.id);
          },
        });
        //阻止火狐拖拽新建新页面
        document.body.addEventListener("drop", this.preventDrop, false);
      });
    },
    //阻止默认drop事件
    preventDrop(event) {
      event.preventDefault();
      event.stopPropagation();
    },
    //销毁拖拽表格
    destroySortable() {
      if (this.$appTable) this.$appTable.destroy();
      document.body.removeEventListener("drop", this.preventDrop, false);
    },
  },
  created() {
    //初始化拖拽表格
    this.initSortable();
  },
  beforeDestroy() {
    //销毁拖拽表格
    this.destroySortable();
  },
}
</script>

拖拽后的数据获取也很简单,分三步:

onEnd事件表示拖拽结束后,他有一个对象,该对象有两个属性我们可以用到,一个是oldIndex,表示被拖拽的元素之前的index下标,newIndex则是被拖拽的元素新的index下标。

那么开始干:

  1. 从tbody源数据中先拿到一份被拖拽的数据对象,命名为oldItem
  2. 从tbody源数据中删除被拖拽的数据对象
  3. tbody源数据从newIndex位置插入一份oldItem

完事,这样我们的源数据始终和拖拽的可视化数据保持一致,所以我们可以直接遍历源数据得到一份最新的基于当前拖拽顺序的id数组,当然也可以是其他,看tbody里面有啥。

注意:

  1. 一定要设置row-key="id",否则拖拽后会莫名其妙
  2. 火狐浏览器拖拽默认会新建新页面,解决这个问题就是阻止body的默认拖拽行为。

以上就是使用方式了。顺带一提querySelector的兼容性还是ok的,放心使用。

分类: vue 项目实战 标签: 排序拖拽elementtablesortablejs

评论

暂无评论数据

暂无评论数据

目录