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

相关推荐
林恒smileZAZ5 小时前
用 Vue 3 + Electron 做桌宠:从启动退出到拖拽、单击与鼠标穿透
vue.js·electron·计算机外设
软件技术NINI6 小时前
基于JavaWeb 汽车租聘
java·vue.js·spring boot·后端·python·毕业设计·毕设
2301_322414280413 小时前
基于SpringBoot+Vue的休闲零食超市管理系统的设计与实现59004-计算机毕设 原创(免费领源码+部署教程+开发环境)
java·vue.js·spring boot·redis·mysql·决策树·推荐算法
酷炫码神19 小时前
Day 8|Vue3 响应式:告别手动操作 DOM,让数据驱动界面
javascript·vue.js·ecmascript
8年车载测试20 小时前
车载测试中如何通过 Jira 平台提交 Bug:操作步骤与关键要点
bug·jira·uds诊断·hil测试·uds自动化测试·ecu刷写测试·canoe工具
星光不问赶路人21 小时前
Vue 3 对象监听与快照:ref 和 reactive 的关键差异
前端·vue.js
稻草人47821 小时前
Vue3.0项目创建步骤
vue.js
Bug收容所1 天前
Vue+js Day2
前端·javascript·vue.js
honkun61 天前
vue 下拉树组件 vxe-table-select 实现分页多选
前端·javascript·vue.js
溪语流沙1 天前
【Web全栈进阶】监控与告警:线上系统的“体检报告”
前端·vue.js·python·fastapi