vue 实现 表格拖拽 包括表格嵌套表格拖拽

在上篇文章实现了表格嵌套表格 上移下移置顶置底的基础上(请看vue 表格嵌套表格 实现上移下移置顶置底),本篇将在此基础上实现拖拽功能。

	openDrag(row) {
      //子表格展开时获取index
      var index = this.tableData.findIndex(item => {
        return item.id === row.id;
      });
      this.setSort2(index);
      this.index = index;
    },
     //没有子集的排序
    setSort() {
      this.sortable = null;
      this.$nextTick(() => {
        const el = this.$refs.dragTable.$el.querySelectorAll(
          ".el-table__body-wrapper > table > tbody"
        )[0];
        this.sortable = Sortable.create(el, {
          ghostClass: "sortable-ghost",
          setData: dataTransfer => {
            dataTransfer.setData("Text", "");
          },
          onEnd: evt => {
            let temp = this.tableData.splice(evt.oldIndex, 1)[0];
            this.tableData.splice(evt.newIndex, 0, temp);
            // that.$forceUpdate();
            this.dragKey1 = Math.random();
            this.setSort();
          }
        });
      });
    },
    setSort2(index) {
      this.sortable = null;
      this.$nextTick(() => {
        if (!this.$refs["dragTable2-" + index]) {
          return;
        }
        const el = this.$refs["dragTable2-" + index].$el.querySelectorAll(
          ".el-table__body-wrapper > table > tbody"
        )[0];
        this.sortable = Sortable.create(el, {
          ghostClass: "sortable-ghost",
          setData: dataTransfer => {
            dataTransfer.setData("Text", "");
          },
          onEnd: evt => {
            console.log("old:", evt.oldIndex);
            console.log("new:", evt.newIndex);
            let temp = this.tableData[index].children.splice(
              evt.oldIndex,
              1
            )[0];
            this.tableData[index].children.splice(evt.newIndex, 0, temp);
            this.dragKey2 = Math.random();
            this.setSort2();
          }
        });
      });
    }

在这里插入图片描述

<template>
  <div>
    <h2>移动</h2>
    <span>表格移动</span>
    <el-card class="box-card">
      <el-table
        ref="dragTable"
        :key="dragKey1"
        :data="tableData"
        style="width: 100%"
        @expand-change="openDrag"
      >
        <el-table-column prop="children" type="expand">
          <template slot-scope="props">
            <el-table
              :ref="'dragTable2-' + props.$index"
              :key="dragKey2"
              row-key="id"
              :data="props.row.children"
              style="width: 100%"
            >
              <el-table-column label="ID" prop="id" />
              <el-table-column label="名称" prop="name" />
              <el-table-column label="操作" min-width="250px">
                <template slot-scope="scope">
                  <el-button
                    type="text"
                    @click.stop="handleTop(scope.$index, scope.row, 1)"
                    v-if="scope.$index != 0"
                    >置顶
                  </el-button>
                  <el-button
                    type="text"
                    @click.stop="handleUp(scope.$index, scope.row, 1)"
                    v-if="scope.$index != 0"
                    >向上
                  </el-button>
                  <el-button
                    type="text"
                    @click.stop="handleDown(scope.$index, scope.row, 1)"
                    v-if="scope.$index != tableData[index].children.length - 1"
                    >向下
                  </el-button>
                  <el-button
                    type="text"
                    @click.stop="handleBottom(scope.$index, scope.row, 1)"
                    v-if="scope.$index != tableData[index].children.length - 1"
                    >置底
                  </el-button>
                  <el-button
                    type="text"
                    label="Drag"
                    width="80"
                    icon="el-icon-rank"
                  >
                  </el-button>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>
        <el-table-column label="单号" prop="id" />
        <el-table-column label="名称" prop="name" />
        <el-table-column label="价格" prop="price" />
        <el-table-column label="总数量" prop="num" />
        <el-table-column label="操作" min-width="250px">
          <template slot-scope="scope">
            <el-button
              type="text"
              @click.stop="handleTop(scope.$index, scope.row)"
              v-if="scope.$index != 0"
              >置顶
            </el-button>
            <el-button
              type="text"
              @click.stop="handleUp(scope.$index, scope.row)"
              v-if="scope.$index != 0"
              >向上
            </el-button>
            <el-button
              type="text"
              @click.stop="handleDown(scope.$index, scope.row)"
              v-if="scope.$index != tableData.length - 1"
              >向下
            </el-button>
            <el-button
              type="text"
              @click.stop="handleBottom(scope.$index, scope.row)"
              v-if="scope.$index != tableData.length - 1"
              >置底
            </el-button>
            <el-button type="text" label="Drag" width="80" icon="el-icon-rank">
            </el-button>
          </template>
        </el-table-column>
      </el-table>
    </el-card>

    <div>
      <span
        >第一层数据顺序:<span v-for="item in tableData" :key="item.id">{{
          item.name
        }}</span></span
      >
    </div>
  </div>
</template>
<script>
import Sortable from "sortablejs";
export default {
  components: { Sortable },
  data() {
    return {
      dragKey1: Math.random(),
      dragKey2: Math.random(),
      tableData: [
        {
          id: "1298712333232",
          key: "1029733292929",
          name: "花甲",
          price: "15.9",
          num: "888",
          children: [
            { id: "1", key: "1029733292929", name: "随便" },
            { id: "2", key: "1029733292929", name: "随便2" },
            { id: "3", key: "1029733292929", name: "随便3" },
            { id: "4", key: "1029733292929", name: "随便4" },
            { id: "5", key: "1029733292929", name: "随便5" },
            { id: "6", key: "1029733292929", name: "随便6" }
          ]
        },
        {
          id: "1489033233442",
          name: "鸡翅",
          price: "152.9",
          key: "1029733332909",
          num: "18",
          children: [
            { id: "1", key: "1029733332909", name: "随便" },
            { id: "2", key: "1029733332909", name: "随便2" }
          ]
        },
        {
          id: "1093443434",
          name: "鸡腿",
          key: "1029733332783",
          price: "23.98",
          num: "38",
          children: [
            { id: "1", key: "1029733332783", name: "随便" },
            { id: "2", key: "1029733332783", name: "随便2" }
          ]
        },
        {
          id: "19232243434",
          name: "小面包",
          price: "10.8",
          num: "30",
          children: [
            { id: "1", key: "1022333332783", name: "随便" },
            { id: "2", key: "1029734032783", name: "随便2" }
          ]
        }
      ]
    };
  },
  created() {
    this.setSort();
  },
  methods: {
    //通过key 查找二级表格上一级 index
    getIndex(arr, item) {
      for (var i = 0; i < arr.length; i++) {
        if (arr[i].key == item.key) {
          return i;
        }
      }
    },
    //处理置顶置底
    handleTopDown(index, row, type, moveType) {
      let tempIndex = this.getIndex(this.tableData, row);
      let temp, arr;
      if (type !== 1) {
        temp = this.tableData.splice(index, 1)[0];
        arr = this.tableData;
      } else {
        // 将要置底的元素存储后删除
        temp = this.tableData[tempIndex].children.splice(index, 1)[0];
        arr = this.tableData[tempIndex].children;
      }
      // 将元素push到数组最后一位
      return moveType === "top" ? arr.unshift(temp) : arr.push(temp);
    },
    // 置顶
    handleTop(index, row, type) {
      this.handleTopDown(index, row, type, "top");
    },
    // 置底
    handleBottom(index, row, type) {
      this.handleTopDown(index, row, type, "down");
    },
    // 调整顺序,arr 数组,indexAdd 添加元素的位置,indexDel 删除元素的位置(indexAdd与indexDel交换位置)
    handleChangeOrder(arr, indexAdd, indexDel, row, type) {
      let tempIndex = this.getIndex(arr, row);
      //判断一级还是二级
      let tempArr = type !== 1 ? arr : arr[tempIndex].children;
      tempArr[indexAdd] = tempArr.splice(indexDel, 1, tempArr[indexAdd])[0];
      return tempArr;
    },
    // 上移,与前一个元素交换顺序
    handleUp(index, row, type) {
      this.handleChangeOrder(this.tableData, index, index - 1, row, type);
    },
    // 下移,与后一个元素交换顺序
    handleDown(index, row, type) {
      this.handleChangeOrder(this.tableData, index, index + 1, row, type);
    },
    openDrag(row) {
      //子表格展开时获取index
      var index = this.tableData.findIndex(item => {
        return item.id === row.id;
      });
      console.log("999");
      this.setSort2(index);
      this.index = index;
    },
    //没有子集的排序
    setSort() {
      this.sortable = null;
      this.$nextTick(() => {
        const el = this.$refs.dragTable.$el.querySelectorAll(
          ".el-table__body-wrapper > table > tbody"
        )[0];
        console.log(this.$refs);
        console.log(el);
        this.sortable = Sortable.create(el, {
          ghostClass: "sortable-ghost",
          setData: dataTransfer => {
            dataTransfer.setData("Text", "");
          },
          onEnd: evt => {
            let temp = this.tableData.splice(evt.oldIndex, 1)[0];
            this.tableData.splice(evt.newIndex, 0, temp);
            // that.$forceUpdate();
            this.dragKey1 = Math.random();
            this.setSort();
          }
        });
      });
    },
    setSort2(index) {
      this.sortable = null;
      this.$nextTick(() => {
        if (!this.$refs["dragTable2-" + index]) {
          return;
        }
        const el = this.$refs["dragTable2-" + index].$el.querySelectorAll(
          ".el-table__body-wrapper > table > tbody"
        )[0];
        console.log(this.$refs);
        console.log(el);
        this.sortable = Sortable.create(el, {
          ghostClass: "sortable-ghost",
          setData: dataTransfer => {
            dataTransfer.setData("Text", "");
          },
          onEnd: evt => {
            console.log("old:", evt.oldIndex);
            console.log("new:", evt.newIndex);
            let temp = this.tableData[index].children.splice(
              evt.oldIndex,
              1
            )[0];
            this.tableData[index].children.splice(evt.newIndex, 0, temp);
            this.dragKey2 = Math.random();
            this.setSort2();
          }
        });
      });
    }
  }
};
</script>

<style lang="scss" scoped>
.box-card {
  width: 90%;
  margin: 0 auto;
  margin-top: 20px;
}
.sortable-ghost {
  opacity: 0.8;
  background: rgba(36, 118, 224, 0.1) !important;
}
</style>

Logo

前往低代码交流专区

更多推荐