解决Sortable拖动el-table表头时,由于选择列造成的拖拽顺序错乱的bug

  • 原因 由于我的表头是由数组循环遍历生成的,而选择列不在数组内,只能在循环外定义el-table-column,造成拖动时索引错乱
  • 错误代码
javascript 复制代码
  <el-table
    @header-dragend="headerDragend"
    id="out-table"
    :data="state.sliceTable"
    border
    stripe
    ref="TableRef"
    :row-key="getRowKeys(pageData)"
  >
  <el-table-column type="selection" width="55" fixed /> 
>
    <template v-for="(item, index) in state.pageDataTitle" :key="index"> 
      <el-table-column
        :prop="item.value"
        :label="item.name"
        :key="index"
      >
        <template #default="scope">
          <slot :name="item.value" :scope="scope">{{ scope.row[item.value] }}</slot>
        </template>
      </el-table-column>
    </template>
  </el-table>
  • 解决办法 向数组开头push一条 type="selection" 的对象 并把el-table-column 写到循环体内
javascript 复制代码
  <template v-for="(item, index) in state.pageDataTitle" :key="index">
    <el-table-column type="selection" v-if="item.type" width="55" fixed />
    <el-table-column
      :prop="item.value"
      :label="item.name"
      :key="index"
    >
      <template #default="scope">
        <slot :name="item.value" :scope="scope">{{ scope.row[item.value] }}</slot>
      </template>
    </el-table-column>
  </template>
  • 当拖动选择列 或 拖向选择列时 仍然会造成拖动顺序混乱 所以我们要禁止掉
  • 给el-table-column添加 class-name="allowdrag" 表示除了选择列之外都可以拖动
javascript 复制代码
  <el-table-column
    class-name="allowdrag"
    :label="item.name"
    :key="index"
  >
    <template #default="scope">
      <slot :name="item.value" :scope="scope">{{ scope.row[item.value] }}</slot>
    </template>
  </el-table-column>
javascript 复制代码
//拖拽列
const columnDrop2 = (dom) => {
  if (!dom) return
  Sortable.create(dom.$el.querySelector('.el-table__header-wrapper>.el-table__header tr'), {
    handle: '.allowdrag',  //除了选择列都可以选择
    onEnd: (sortableEvent) => {
      const targetThElem = sortableEvent.item;
      const wrapperElem = targetThElem.parentNode;
      const newIndex = sortableEvent.newIndex;
      const oldIndex = sortableEvent.oldIndex;
      const oldTrElement = wrapperElem.children[oldIndex];
      const currRow = state.pageDataTitle?.splice(oldIndex, 1)[0];
      state.pageDataTitle?.splice(newIndex, 0, currRow);
      if (newIndex > oldIndex) {
        wrapperElem.insertBefore(targetThElem, oldTrElement)
      } else {
        wrapperElem.insertBefore(
          targetThElem,
          oldTrElement ? oldTrElement.nextElementSibling : oldTrElement
        )
      }

    },
  })
}
  • 这样解决了选择列向其他列拖动 ,但没有解决其他列向选择列拖动
  • 解决办法 添加 :header-cell-class-name="tableRowClassName" 并添加onMove方法
javascript 复制代码
  <el-table
    :header-cell-class-name="tableRowClassName"
    id="out-table"
    :data="state.sliceTable"
    ref="TableRef"
  >
    <template v-for="(item, index) in state.pageDataTitle" :key="index">
      <el-table-column type="selection" v-if="item.type" width="55" fixed />
      <el-table-column
        class-name="allowdrag"
        :prop="item.value"
        :label="item.name"
        :key="index"
      >
        <template #default="scope">
          <slot :name="item.value" :scope="scope">{{ scope.row[item.value] }}</slot>
        </template>
      </el-table-column>
    </template>
  </el-table>
javascript 复制代码
//解决向选择列拖动的bug
 function tableRowClassName(row) {
      if (row.columnIndex == 0) {
        return "filtered";
      }
      return "";
    }
javascript 复制代码
//拖拽列
const columnDrop2 = (dom) => {
    if (!dom) return
    Sortable.create(dom.$el.querySelector('.el-table__header-wrapper>.el-table__header tr'), {
        handle: '.allowdrag',
        onEnd: (sortableEvent) => {
            const targetThElem = sortableEvent.item;
            const wrapperElem = targetThElem.parentNode;
            const newIndex = sortableEvent.newIndex;
            const oldIndex = sortableEvent.oldIndex;
            const oldTrElement = wrapperElem.children[oldIndex];
            const currRow = state.pageDataTitle?.splice(oldIndex, 1)[0];
           state.pageDataTitle?.splice(newIndex, 0, currRow)
            if (newIndex > oldIndex) {
                wrapperElem.insertBefore(targetThElem, oldTrElement)
            } else {
                wrapperElem.insertBefore(
                    targetThElem,
                    oldTrElement ? oldTrElement.nextElementSibling : oldTrElement
                )
            }

        },
        //解决向选择列拖动的bug
        onMove(e) {
        return e.related.className.indexOf("filtered") === -1;
      }
    })
}

完整代码

javascript 复制代码
  <el-table
    :header-cell-class-name="tableRowClassName"
    id="out-table"
    :data="state.sliceTable"
    ref="TableRef"
  >
    <template v-for="(item, index) in state.pageDataTitle" :key="index">
      <el-table-column type="selection" v-if="item.type" width="55" fixed />
      <el-table-column
        class-name="allowdrag"
        :prop="item.value"
        :label="item.name"
        :key="index"
      >
        <template #default="scope">
          <slot :name="item.value" :scope="scope">{{ scope.row[item.value] }}</slot>
        </template>
      </el-table-column>
    </template>
  </el-table>
javascript 复制代码
//拖拽列
const columnDrop2 = (dom) => {
    if (!dom) return
    Sortable.create(dom.$el.querySelector('.el-table__header-wrapper>.el-table__header tr'), {
        handle: '.allowdrag',
        onEnd: (sortableEvent) => {
            const targetThElem = sortableEvent.item;
            const wrapperElem = targetThElem.parentNode;
            const newIndex = sortableEvent.newIndex;
            const oldIndex = sortableEvent.oldIndex;
            const oldTrElement = wrapperElem.children[oldIndex];
            const currRow = state.pageDataTitle?.splice(oldIndex, 1)[0];
           state.pageDataTitle?.splice(newIndex, 0, currRow)
            if (newIndex > oldIndex) {
                wrapperElem.insertBefore(targetThElem, oldTrElement)
            } else {
                wrapperElem.insertBefore(
                    targetThElem,
                    oldTrElement ? oldTrElement.nextElementSibling : oldTrElement
                )
            }

        },
        //解决向选择列拖动的bug
        onMove(e) {
        return e.related.className.indexOf("filtered") === -1;
      }
    })
}

//解决向选择列拖动的bug
 function tableRowClassName(row) {
      if (row.columnIndex == 0) {
        return "filtered";
      }
      return "";
    }

效果图

QQ录屏20231211155823

相关推荐
MaCa .BaKa18 分钟前
56-非遗手工艺品定制平台系统
java·vue.js·spring boot·mysql·maven·非遗手工制作平台系统·非遗制作
无聊的老谢27 分钟前
Vue 3 + Leaflet 实现高性能 Web GIS 基站监控平台
前端·javascript·vue.js
前端 贾公子28 分钟前
3.响应式系统基础:从发布订阅模式的角度理解 Vue2 的数据响应式原理(上)
前端·javascript·vue.js
xiaohua0708day14 小时前
Lodash库
前端·javascript·vue.js
万物皆对象66614 小时前
切换路由时页面空白问题(vue3)
前端·vue.js·typescript
李剑一16 小时前
小红书前端架构面试问的挺深入啊!面试官:Vue中组合式API与选项式API的设计权衡
vue.js·面试
一 乐17 小时前
汽车租赁|基于SprinBoot+vue的汽车租赁管理系统(源码+数据库+文档)
数据库·vue.js·spring boot·汽车·论文·毕设·汽车租赁管理系统
MaCa .BaKa21 小时前
55-宠物爱心救助领养系统-宠物救助领养系统
java·vue.js·tomcat·maven·springboot·宠物救助领养系统
lili001221 小时前
Claude自动修Bug配置优化与避坑指南
java·人工智能·python·bug·ai编程
海鸥两三1 天前
基于 Vue 3 + 高德地图的网格规划系统实战(有源码)
前端·javascript·vue.js