VUE3+elementPlus 表格动态列+原生JS拖拽

112 阅读1分钟

先介绍下原生JS的drag事件:

image.png 需要注意拷贝重置数组,列表渲染的数组也要隔离开,不然一选择都会跟着变. 

image.png  数据源于:blog.csdn.net/qq_36384657…

全部源码:

<template>
  <div>
    <div style="width=300px;float: left; margin-bottom: 10px;">
      <el-button type="primary" @click="visible = true">字段配置</el-button>
    </div>
    <el-popover
      :visible="visible"
      placement="bottom"
      trigger="click"
      title="自定义展示列表"
      width="200"
      virtual-triggering>
      <el-checkbox
        style="width: 120px"
        v-for="(item, index) in cloumns"
        v-model="item.visible"
        :key="item.prop"
        :label="item.label"
        :draggable="true"
        @dragstart="dragStartFn(index)"
        @dragenter="dragEnterFn($event, index)"
        @dragover="dragoverFn($event, index)" />
      <el-divider style="margin: 10px 0" />
      <div style="width: 135px; margin: 0 auto">
        <el-button @click="reset">重置</el-button>
        <el-button type="primary" @click="confirm">确定</el-button>
      </div>
    </el-popover>
    <div>
      <el-table
        :data="tableData"
        style="width: 100%"
        border
        :tree-props="{ children: 'children' }"
        ref="table">
        <el-table-column
          v-for="(item, index) in cloumnsCOM"
          :prop="item.prop"
          :label="item.label"
          :key="index" />
      </el-table>
    </div>
  </div>
</template>

<script setup lang="ts">
import { ref, computed, onBeforeMount } from "vue";
//多选框绑定数据
const cloumns = ref([
  { label: "计划名称", prop: "planName", visible: true },
  { label: "编号", prop: "id", visible: true },
  { label: "计划开始日期", prop: "beginTimeP", visible: true },
  { label: "计划完成日期", prop: "endTimeP", visible: true },
  { label: "实际开始日期", prop: "beginTimeS", visible: true },
  { label: "实际完成日期", prop: "endTimeS", visible: true },
  { label: "状态", prop: "status", visible: false },
  { label: "逾期状态", prop: "delayStatus", visible: false },
  { label: "备注", prop: "remark", visible: false },
]);
const tableData = ref([
  {
    id: "001",
    planName: "ffff",
    beginTimeP: "2022-02-03",
    endTimeP: "2022-02-03",
    beginTimeS: "2022-02-03",
    endTimeS: "2022-02-03",
    children: [
      {
        id: "00101",
        planName: "ffff",
        beginTimeP: "2022-02-03",
        endTimeP: "2022-02-03",
        beginTimeS: "2022-02-03",
        endTimeS: "2022-02-03",
      },
      {
        id: "00102",
        planName: "ffff",
        beginTimeP: "2022-02-03",
        endTimeP: "2022-02-03",
        beginTimeS: "2022-02-03",
        endTimeS: "2022-02-03",
      },
      {
        id: "00103",
        planName: "ffff",
        beginTimeP: "2022-02-03",
        endTimeP: "2022-02-03",
        beginTimeS: "2022-02-03",
        endTimeS: "2022-02-03",
      },
      {
        id: "00104",
        planName: "ffff",
        beginTimeP: "2022-02-03",
        endTimeP: "2022-02-03",
        beginTimeS: "2022-02-03",
        endTimeS: "2022-02-03",
      },
    ],
  },
  {
    id: "002",
    planName: "uuuu",
    beginTimeP: "2022-02-03",
    endTimeP: "2022-02-03",
    beginTimeS: "2022-02-03",
    endTimeS: "2022-02-03",
    children: [
      {
        id: "00201",
        planName: "ffff",
        beginTimeP: "2022-02-03",
        endTimeP: "2022-02-03",
        beginTimeS: "2022-02-03",
        endTimeS: "2022-02-03",
      },
      {
        id: "00202",
        planName: "ffff",
        beginTimeP: "2022-02-03",
        endTimeP: "2022-02-03",
        beginTimeS: "2022-02-03",
        endTimeS: "2022-02-03",
      },
    ],
  },
  {
    id: "003",
    planName: "yyyy",
    beginTimeP: "2022-02-03",
    endTimeP: "2022-02-03",
    beginTimeS: "2022-02-03",
    endTimeS: "2022-02-03",
    children: [
      {
        id: "00301",
        planName: "ffff",
        beginTimeP: "2022-02-03",
        endTimeP: "2022-02-03",
        beginTimeS: "2022-02-03",
        endTimeS: "2022-02-03",
      },
      {
        id: "00302",
        planName: "ffff",
        beginTimeP: "2022-02-03",
        endTimeP: "2022-02-03",
        beginTimeS: "2022-02-03",
        endTimeS: "2022-02-03",
      },
    ],
  },
  {
    id: "004",
    planName: "xxxx",
    beginTimeP: "2022-02-03",
    endTimeP: "2022-02-03",
    beginTimeS: "2022-02-03",
    endTimeS: "2022-02-03",
    children: [
      {
        id: "00401",
        planName: "ffff",
        beginTimeP: "2022-02-03",
        endTimeP: "2022-02-03",
        beginTimeS: "2022-02-03",
        endTimeS: "2022-02-03",
      },
      {
        id: "00402",
        planName: "ffff",
        beginTimeP: "2022-02-03",
        endTimeP: "2022-02-03",
        beginTimeS: "2022-02-03",
        endTimeS: "2022-02-03",
      },
    ],
  },
]);
// 重置数据
const reCloumns = ref([]);
//列表渲染数据深拷贝
const tempCloumns = ref([]);
const cloumnsCOM = computed(() => {
  return (tempCloumns.value as any).filter((item) => item.visible);
});
onBeforeMount(() => {
  tempCloumns.value = JSON.parse(JSON.stringify(cloumns.value));
  reCloumns.value = JSON.parse(JSON.stringify(cloumns.value));
});
const visible = ref(false);
// 拖动
const dragIndex = ref(0);
const enterIndex = ref(0);
const dragStartFn = (index: number) => {
  dragIndex.value = index;
};
const dragEnterFn = (e: any, index: number) => {
  e.preventDefault();
  enterIndex.value = index;
  const source = cloumns.value[dragIndex.value];
  cloumns.value.splice(dragIndex.value, 1);
  cloumns.value.splice(index, 0, source);
  dragIndex.value = index;
};
const dragoverFn = (e: any, index: number) => {
  e.preventDefault();
};
const confirm = () => {
  tempCloumns.value = JSON.parse(JSON.stringify(cloumns.value));
  visible.value = false;
};
const reset = () => {
  cloumns.value = JSON.parse(JSON.stringify(reCloumns.value));
  tempCloumns.value = JSON.parse(JSON.stringify(reCloumns.value));
  visible.value = false;
};
</script>