废话不多说,上代码:
js如下:
/**
* 表格拖拽
* @param tableData 表格数据
* @param el 表格元素
*/
const dragTable = {
el: null as any,
dragover: null as any,
drop: null as any,
dragstart: null as any,
init(tableData: any[], el: HTMLElement, callback: Function) {
dragTable.el = el
const dragover: any = dragTable.dragover = (ev: DragEvent) => {
ev.preventDefault();
}
const drop: any = dragTable.drop = (ev: DragEvent) => {
ev.preventDefault();
var index = ev.dataTransfer?.getData("index");
const path = ev.composedPath();
const tr = path.find(el => el instanceof HTMLElement && el.tagName === 'TR') as HTMLElement | undefined;
let end = null, start = index;
if (tr) {
const index = tr.dataset.index
end = index
}
if (end !== null && start != end) {
const _start = parseInt(start || '0')
const _end = parseInt(end || '0')
const max = Math.max(_start, _end)
const min = Math.min(_start, _end)
const a = tableData.splice(max, 1)
const b = tableData.splice(min, 1, a[0])
tableData.splice(max, 0, b[0])
callback?.({
start, end
})
}
}
const dragstart: any = dragTable.dragstart = (ev: DragEvent) => {
const { index } = ev.target?.dataset
ev.dataTransfer?.setData("index", index);
}
const table = el.querySelector('.el-table__body-wrapper')
const trs = table?.querySelectorAll('tr.el-table__row')
if (table && trs) {
table.addEventListener('dragover', dragover, true)
table.addEventListener('drop', drop, true)
trs.forEach((tr, index) => {
tr.setAttribute('draggable', 'true')
tr.setAttribute('data-index', index + '')
tr.addEventListener('dragstart', dragstart, true)
})
}
},
remove() {
const el = dragTable.el
const table = el?.querySelector('.el-table__body-wrapper')
const trs = table?.querySelectorAll('tr.el-table__row')
if (table && trs) {
table.removeEventListener('dragover', dragTable.dragover)
table.removeEventListener('drop', dragTable.drop)
trs.forEach((tr: HTMLElement) => {
tr.removeEventListener('dragstart', dragTable.dragstart)
})
}
},
}
export { dragTable }
使用demo如下:
<template>
<div class="drag-box" ref="dragBox">
<el-table :data="tableData" style="width: 100%" :row-class-name="tableRowClassName">
<el-table-column prop="date" label="Date" width="180" />
<el-table-column prop="name" label="Name" width="180" />
<el-table-column prop="address" label="Address" width="360" />
</el-table>
</div>
</template>
<script lang="ts" setup>
import { ref, onMounted, onUnmounted } from 'vue';
import { dragTable } from '@/utils/utils'
const dragBox = ref<HTMLElement | null>(null)
interface User {
date: string
name: string
address: string
}
const tableRowClassName = ({
row,
rowIndex,
}: {
row: User
rowIndex: number
}) => {
if (rowIndex === 1) {
return 'warning-row'
} else if (rowIndex === 3) {
return 'success-row'
}
return ''
}
const tableData = ref<User[]>([
{
date: '2016-05-01',
name: '张三',
address: '四川',
},
{
date: '2016-05-02',
name: '李四',
address: '山西',
},
{
date: '2016-05-03',
name: '王五',
address: '湖南',
},
{
date: '2016-05-04',
name: '刘六',
address: '新疆',
},
])
onMounted(() => {
dragTable.init(tableData.value, dragBox.value, (data: any) => {
console.log(data)
})
})
onUnmounted(() => {
dragTable.remove()
})
</script>
<style>
.el-table .warning-row {
--el-table-tr-bg-color: var(--el-color-warning-light-9);
}
.el-table .success-row {
--el-table-tr-bg-color: var(--el-color-success-light-9);
}
</style>