vue3 实现el-tabel 行的拖拽排序
时间: 2023-11-17 07:17:48 浏览: 161
要实现el-table的行拖拽排序,可以使用Vue3的拖拽指令`v-drag`。具体步骤如下:
1. 在el-table的每一行上添加`v-drag`指令:
```html
<el-table>
<el-table-column label="序号" type="index"></el-table-column>
<el-table-column label="名称" prop="name"></el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button @click="deleteRow(scope.$index)">删除</el-button>
</template>
</el-table-column>
<el-table-column label="排序">
<template slot-scope="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column label="拖拽排序" width="80">
<template slot-scope="scope">
<div class="drag-handle" v-drag>
<i class="el-icon-s-grid"></i>
</div>
</template>
</el-table-column>
</el-table>
```
2. 在Vue3组件中定义`v-drag`指令:
```javascript
import { DirectiveBinding } from 'vue';
interface DragData {
el: HTMLElement;
startX: number;
startY: number;
lastX: number;
lastY: number;
targetIndex: number;
}
const dragData: DragData = {
el: null,
startX: 0,
startY: 0,
lastX: 0,
lastY: 0,
targetIndex: 0,
};
function handleDragStart(event: MouseEvent) {
const target = event.target as HTMLElement;
const tableRow = target.closest('.el-table__row');
if (tableRow) {
dragData.el = tableRow;
dragData.startX = event.clientX;
dragData.startY = event.clientY;
dragData.lastX = event.clientX;
dragData.lastY = event.clientY;
dragData.targetIndex = parseInt(tableRow.dataset.index);
tableRow.style.opacity = '0.5';
}
}
function handleDragEnd() {
if (dragData.el) {
dragData.el.style.opacity = '1';
dragData.el = null;
}
}
function handleDrag(event: MouseEvent) {
if (dragData.el) {
const deltaX = event.clientX - dragData.lastX;
const deltaY = event.clientY - dragData.lastY;
dragData.el.style.transform = `translate(${deltaX}px, ${deltaY}px)`;
dragData.lastX = event.clientX;
dragData.lastY = event.clientY;
}
}
function handleDrop(event: MouseEvent) {
if (dragData.el) {
const target = event.target as HTMLElement;
const tableRow = target.closest('.el-table__row');
if (tableRow) {
const targetIndex = parseInt(tableRow.dataset.index);
if (targetIndex !== dragData.targetIndex) {
const tableBody = dragData.el.closest('.el-table__body-wrapper');
const tableRows = Array.from(tableBody.querySelectorAll('.el-table__row'));
const dragIndex = tableRows.indexOf(dragData.el);
const removed = tableRows.splice(dragIndex, 1);
tableRows.splice(targetIndex < dragIndex ? targetIndex : targetIndex - 1, 0, removed[0]);
tableRows.forEach((row, index) => {
row.dataset.index = index.toString();
row.style.transform = '';
});
}
}
handleDragEnd();
}
}
export default {
mounted(el: HTMLElement, binding: DirectiveBinding) {
el.addEventListener('mousedown', handleDragStart);
document.addEventListener('mouseup', handleDrop);
document.addEventListener('mousemove', handleDrag);
},
unmounted() {
document.removeEventListener('mouseup', handleDrop);
document.removeEventListener('mousemove', handleDrag);
},
};
```
3. 在组件中引入`v-drag`指令,并绑定到el-table的拖拽排序列上:
```javascript
<template>
<el-table>
<el-table-column label="序号" type="index"></el-table-column>
<el-table-column label="名称" prop="name"></el-table-column>
<el-table-column label="操作">
<template slot-scope="scope">
<el-button @click="deleteRow(scope.$index)">删除</el-button>
</template>
</el-table-column>
<el-table-column label="排序">
<template slot-scope="scope">
<span>{{ scope.$index + 1 }}</span>
</template>
</el-table-column>
<el-table-column label="拖拽排序" width="80">
<template slot-scope="scope">
<div class="drag-handle" v-drag>
<i class="el-icon-s-grid"></i>
</div>
</template>
</el-table-column>
</el-table>
</template>
<script>
import vDrag from './v-drag';
export default {
directives: {
drag: vDrag,
},
methods: {
deleteRow(index) {
// ...
},
},
};
</script>
```
4. 完成后,就可以实现el-table的行拖拽排序了。
阅读全文