用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数据表格可编辑表格单元格值修改之后获取修改前的值
379 0
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
713 0
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
|
7月前
elementUI 写一个表头列名、表体单元格样式、翻页器相对较为动态的表格el-table
elementUI 写一个表头列名、表体单元格样式、翻页器相对较为动态的表格el-table
elementUI 写一个表头列名、表体单元格样式、翻页器相对较为动态的表格el-table
|
JavaScript BI
el-table 多表格弹窗嵌套数据显示异常错乱问题
## 1、业务背景 使用vue+element开发报表功能时,需要列表上某列的超链接按钮弹窗展示,在弹窗的el-table列表某列中再次使用超链接按钮点开弹窗,以此类推多表格弹窗嵌套,本文以弹窗两次为例 最终效果如下示例页面 ![微信截图_20231110143638.png](https://ucc.alicdn.com/pic/developer-ecology/j2ygdazy447va_6eb0201441bc40a4b5bda9a7e573f0d2.png)
231 0
|
JavaScript
jqGrid数据列表和表单的列隐藏/显示
jqGrid数据列表和表单的列隐藏/显示
119 0
jqgrid实现表头合并功能
jqgrid实现表头合并功能
385 0
|
存储 前端开发 数据库
el-table表格拖动列记住列宽度功能(刷新页面还在)
el-table表格拖动列记住列宽度功能(刷新页面还在)
469 0
|
Python
【Excel自动化办公Part2】:向某个格子里写入内容、append()插入行、在表格中插入公式、插入行和列、删除行和列、移动格子
【Excel自动化办公Part2】:向某个格子里写入内容、append()插入行、在表格中插入公式、插入行和列、删除行和列、移动格子
232 0
【Excel自动化办公Part2】:向某个格子里写入内容、append()插入行、在表格中插入公式、插入行和列、删除行和列、移动格子
拖拽排序-列表布局
拖拽排序-列表布局
191 0
拖拽排序-列表布局
ElementUI:表格table列宽度压缩出现空白
ElementUI:表格table列宽度压缩出现空白
222 0
ElementUI:表格table列宽度压缩出现空白