用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数据表格可编辑表格单元格值修改之后获取修改前的值
352 0
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
694 0
PyQt5 技术篇-QTableWidget表格组件指定行的隐藏与显示控制实例演示,设置表格指定列的列宽方法
|
6月前
|
小程序
06 - table表格标签+ 行合并+列合并
06 - table表格标签+ 行合并+列合并
128 0
|
JavaScript BI
el-table 多表格弹窗嵌套数据显示异常错乱问题
## 1、业务背景 使用vue+element开发报表功能时,需要列表上某列的超链接按钮弹窗展示,在弹窗的el-table列表某列中再次使用超链接按钮点开弹窗,以此类推多表格弹窗嵌套,本文以弹窗两次为例 最终效果如下示例页面 ![微信截图_20231110143638.png](https://ucc.alicdn.com/pic/developer-ecology/j2ygdazy447va_6eb0201441bc40a4b5bda9a7e573f0d2.png)
199 0
|
JavaScript
jqGrid数据列表和表单的列隐藏/显示
jqGrid数据列表和表单的列隐藏/显示
112 0
|
缓存 JavaScript 前端开发
el-table 列的动态显示与隐藏
当我们在对表格数据查看的时候,可能某些列的数据是当前想要重点关注的,而某些列并不需要展示出来,我们就可以通过对表格的列进行实时的一个切换去实现动态的显示与隐藏。
|
存储 前端开发 数据库
el-table表格拖动列记住列宽度功能(刷新页面还在)
el-table表格拖动列记住列宽度功能(刷新页面还在)
448 0
|
Python
【Excel自动化办公Part2】:向某个格子里写入内容、append()插入行、在表格中插入公式、插入行和列、删除行和列、移动格子
【Excel自动化办公Part2】:向某个格子里写入内容、append()插入行、在表格中插入公式、插入行和列、删除行和列、移动格子
224 0
【Excel自动化办公Part2】:向某个格子里写入内容、append()插入行、在表格中插入公式、插入行和列、删除行和列、移动格子