用dragstart、drag、dragend、dragover、drop、dragleave实现针对表格列的顺序进行拖拽排序(附带实现选择某几列数据显示或隐藏)

简介: 用dragstart、drag、dragend、dragover、drop、dragleave实现针对表格列的顺序进行拖拽排序(附带实现选择某几列数据显示或隐藏)


特性

  1. 可以显示隐藏某一列
  2. 可以圈选显示隐藏所有列(禁用列不受状态影响)
  3. 可以拖拽列名进行前后排序
<template>
  <div :class="$options.name">
    <el-dropdown :show-timeout="0" :placement="`bottom`">
      <el-link :underline="false" style="cursor: default"
        >表格列设置
        <el-tooltip
          :enterable="false"
          effect="dark"
          :content="`可以上下拖拽改变列顺序`"
          placement="top"
          :transition="`none`"
        >
          <i class="el-icon-question"></i>
        </el-tooltip>
        <i class="el-icon-arrow-down"></i>
      </el-link>
      <el-dropdown-menu slot="dropdown" style="transition: none"
        ><el-dropdown-item>
          <el-checkbox
            :indeterminate="checkedHalf"
            :disabled="!tableColumns.some((v) => !v.disabled)"
            v-model="checkedAll"
            @change="changeCheckedAll"
            @click.native.stop
            >全选</el-checkbox
          ></el-dropdown-item
        >
        <el-dropdown-item
          v-for="(item, index) in tableColumns"
          :key="index"
          :divided="item.divided"
          style="padding: 0"
        >
          <div
            :draggable="!item.disabled"
            style="
              padding: 0 20px;
              box-sizing: border-box;
              border: 2px dashed transparent;
            "
            @dragstart="dragstart($event, index)"
            @drag="drag"
            @dragend="dragend"
            @dragover="dragover"
            @drop="drop($event, index)"
            @dragleave="dragleave"
          >
            <el-checkbox
              :disabled="item.disabled"
              v-model="item.checked"
              @click.native.stop
              >{{ item.label }}</el-checkbox
            >
          </div></el-dropdown-item
        >
      </el-dropdown-menu>
    </el-dropdown>
 
    <el-table :data="tableData">
      <el-table-column type="selection" width="50" />
      <el-table-column type="index" label="序号" width="60" />
 
      <!-- 主要列 BEGIN---------------------------------------- -->
      <el-table-column
        v-for="(a, i) in tableColumns"
        v-if="a.checked"
        :key="i"
        :prop="a.prop"
        :label="a.label"
        :width="a.width || `auto`"
      />
      <!-- 主要列 END---------------------------------------- -->
 
      <el-table-column label="操作" width="150">
        <template slot-scope="scope">
          <el-button size="mini" type="primary">修改</el-button>
          <el-button size="mini" type="danger">删除</el-button>
        </template>
      </el-table-column>
    </el-table>
  </div>
</template>
<script>
export default {
  data() {
    return {
      // 表格列字段----------------------------------------
      checkedHalf: false,
      checkedAll: false,
      tableColumns: [
        { prop: "ZD1", label: "字段名称1", width: 110 },
        { prop: "ZD2", label: "字段名称2", width: 200, checked: true, disabled: true },
        { prop: "ZD3", label: "字段名称3", width: 110 },
        { prop: "ZD4", label: "字段名称4", width: 110 },
        { prop: "ZD5", label: "字段名称5", width: 110 },
      ],
      // ----------------------------------------
      tableData: [
        {
          ZD1: "字段1的值-1",
          ZD2: "字段2的值-1",
          ZD3: "字段3的值-1",
          ZD4: "字段4的值-1",
          ZD5: "字段5的值-1",
        },
        {
          ZD1: "字段1的值-2",
          ZD2: "字段2的值-2",
          ZD3: "字段3的值-2",
          ZD4: "字段4的值-2",
          ZD5: "字段5的值-2",
        },
        {
          ZD1: "字段1的值-3",
          ZD2: "字段2的值-3",
          ZD3: "字段3的值-3",
          ZD4: "字段4的值-3",
          ZD5: "字段5的值-3",
        },
        {
          ZD1: "字段1的值-4",
          ZD2: "字段2的值-4",
          ZD3: "字段3的值-4",
          ZD4: "字段4的值-4",
          ZD5: "字段5的值-4",
        },
        {
          ZD1: "字段1的值-5",
          ZD2: "字段2的值-5",
          ZD3: "字段3的值-5",
          ZD4: "字段4的值-5",
          ZD5: "字段5的值-5",
        },
      ], //表格数据
    };
  },
  watch: {
    tableColumns: {
      handler(newValue, oldValue) {
        if (newValue && Object.keys(newValue).length) {
          this.checkedHalf =
            newValue.some((v) => v.checked) && newValue.some((v) => !v.checked); //部分选中
          newValue.every((v) => v.checked) &&
            ((this.checkedAll = true), (this.checkedHalf = false)); //全选中
          this.checkedHalf && (this.checkedAll = false); //未全选中
        }
      },
      deep: true, //深度监听
      immediate: true, //立即执行
    },
  },
 
  methods: {
    changeCheckedAll(checked) {
      let allowItems = this.tableColumns.filter((v) => !v.disabled); //未被禁用的选项
      this.checkedAll = allowItems.some((v) => !v.checked); //在未被禁用的选项中,只要有一个未勾选,点击“全选”就是全选,否者就是全不选
      allowItems.forEach((v) => this.$set(v, "checked", this.checkedAll));
    },
    // 被拖拽物体的监听事件----------------------------------------
    dragstart(e, index) {
      e.dataTransfer.setData("fromIndex", index); //传递拖拽起始位置索引
    },
    drag(e) {
      e.currentTarget.style.opacity = 0.618; //被拖拽元素透明
    },
    dragend(e) {
      e.currentTarget.style.opacity = 1; //被拖拽元素恢复透明
    },
    // 放置区域的监听事件----------------------------------------
    dragover(e) {
      let et = e.currentTarget;
      let lessThanHalf = e.offsetY < et.offsetHeight / 2; //向下拖动鼠标未超过被放置区域一半高度
      et.style.borderTopColor = lessThanHalf ? `#409EFF` : `transparent`; //上边线显示
      et.style.borderBottomColor = !lessThanHalf ? `#409EFF` : `transparent`; //下边线显示
      e.preventDefault();
    },
    drop(e, index) {
      let et = e.currentTarget;
      et.style.borderColor = `transparent`;
      let lessThanHalf = e.offsetY < et.offsetHeight / 2; //向下拖动鼠标未超过被放置区域一半高度
      let fromIndex = e.dataTransfer.getData("fromIndex"); //拖拽起始位置索引
      let toIndex = index; //拖拽到的目标位置索引
      if (fromIndex == toIndex) return; //一样的位置就不改变顺序了
      toIndex =
        fromIndex < toIndex
          ? lessThanHalf
            ? index - 1
            : index
          : lessThanHalf
          ? index
          : index + 1; //拖拽到不同的目标位置索引(注意细节:从下往上拖拽 和 从上往下 拖拽索引的大小不一样)
      this.$g.array.moveArrayElement(this.tableColumns, fromIndex, toIndex); //移动目标元素
    },
    dragleave(e) {
      e.currentTarget.style.borderColor = `transparent`; //清空边框线
    },
  },
};
</script>

应用到了

image.png

用第三方插件实现表格的行拖拽排序

image.png

相关文章
layUI数据表格可编辑表格单元格值修改之后获取修改前的值
layUI数据表格可编辑表格单元格值修改之后获取修改前的值
345 0
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
687 0
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
|
前端开发
dataTable列内容过长隐藏
dataTable列内容过长隐藏
131 0
|
JavaScript
jqGrid数据列表和表单的列隐藏/显示
jqGrid数据列表和表单的列隐藏/显示
112 0
|
JavaScript 前端开发 Java
29jqGrid 3.0新特征- 显示/隐藏列
29jqGrid 3.0新特征- 显示/隐藏列
48 0
|
缓存 JavaScript 前端开发
el-table 列的动态显示与隐藏
当我们在对表格数据查看的时候,可能某些列的数据是当前想要重点关注的,而某些列并不需要展示出来,我们就可以通过对表格的列进行实时的一个切换去实现动态的显示与隐藏。
|
存储 前端开发 数据库
el-table表格拖动列记住列宽度功能(刷新页面还在)
el-table表格拖动列记住列宽度功能(刷新页面还在)
446 0
|
C#
C# 操作Word文本框——插入表格/读取表格/删除表格
在文本框中,我们可以操作很多元素,如文本、图片、表格等,在本篇文章中将着重介绍如何插入表格到文本框,插入的表格我们可以对表格进行格式化操作来丰富表格内容。此外,对于文本框中的表格内容,我们也可以根据需要来读取表格或者删除表格。
1489 0