- 原因 由于我的表头是由数组循环遍历生成的,而选择列不在数组内,只能在循环外定义el-table-column,造成拖动时索引错乱
- 错误代码
<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 写到循环体内
<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" 表示除了选择列之外都可以拖动
<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>
//拖拽列
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方法
<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>
//解决向选择列拖动的bug
function tableRowClassName(row) {
if (row.columnIndex == 0) {
return "filtered";
}
return "";
}
//拖拽列
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;
}
})
}
完整代码
<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>
//拖拽列
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