解决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

相关推荐
眼镜chen11 分钟前
luckysheet的使用——17.将表格作为pdf下载到本地
前端·javascript·vue.js·chrome·pdf
_龙小鱼_29 分钟前
Vue2到Vue3迁移问题解析
前端·javascript·vue.js
二川bro1 小时前
深度解析Vue项目Webpack打包分包策略 从基础配置到高级优化,全面掌握性能优化核心技巧
vue.js·webpack·性能优化
搏博2 小时前
Hbuilder X4.65新建vue3项目存在的问题以及解决办法
前端·javascript·vue.js·ecmascript
孩子 你要相信光2 小时前
vue3/vue2大屏适配
前端·javascript·vue.js
武昌库里写JAVA3 小时前
Iteration in Golang – How to Loop Through Data Structures in Go
java·vue.js·spring boot·学习·课程设计
娃哈哈哈哈呀4 小时前
Vue 3 动态 ref 的使用方式(表格)
前端·javascript·vue.js
小妖6666 小时前
el-breadcrumb 面包屑第一项后面怎么写没有分隔符
javascript·vue.js·elementui
LuckyLay12 小时前
Vue百日学习计划Day33-35天详细计划-Gemini版
前端·vue.js·学习
苹果酱056713 小时前
Golang中的runtime.LockOSThread 和 runtime.UnlockOSThread
java·vue.js·spring boot·mysql·课程设计