表格拖拽排序是一个常见功能
查看效果
准备
加载依赖
我们使用第三方sortablejs来实现
import Sortablejs from "sortablejs";
定义类型
export interface Sortable {
drag?: boolean;
onDrag?: (drag: Drag) => void;
}
增加props
sortable: {
type: Object as PropType<Sortable>,
default: () => ({}),
},
useSortable实现
function useSortable(
sortable: Sortable,
elProTable: Ref,
dataSource: Ref<Data[]>
) {
const drag = sortable.drag;
const onDrag = sortable.onDrag;
drag &&
onMounted(() => {
const tbody = elProTable?.value?.querySelector(
".el-table__body-wrapper tbody"
);
const sortable =
tbody &&
Sortablejs.create(tbody, {
handle: ".sortable-handle", // Restricts sort start click/touch to the specified element
ghostClass: "sortable-ghost", // Class name for the drop placeholder,
setData: function (dataTransfer: any) {
// to avoid Firefox bug
// Detail see : https://github.com/RubaXa/Sortable/issues/1012
dataTransfer.setData("Text", "");
},
onEnd: (evt: any) => {
const targetRow = dataSource.value.splice(evt.oldIndex, 1)[0];
dataSource.value.splice(evt.newIndex, 0, targetRow);
onDrag &&
onDrag({
oldIndex: evt.oldIndex,
newIndex: evt.newIndex,
dataSource: dataSource.value,
});
// for show the changes, you can delete in you code
// const tempIndex = this.newList.splice(evt.oldIndex, 1)[0];
// this.newList.splice(evt.newIndex, 0, tempIndex);
},
});
onUnmounted(() => {
sortable.destroy();
});
});
const node = drag && (
<ElTableColumn width="30" fixed>
<ElIcon class="sortable-handle">
<Menu />
</ElIcon>
</ElTableColumn>
);
return { node };
}
调用
<h2>支持拖拽</h2>
<el-pro-table :data="tableData" :sortable="{ drag: true }">
<el-table-column prop="date" label="Date" />
<el-table-column prop="name" label="Name" />
<el-table-column prop="name" label="Name" />
<el-table-column prop="state" label="State" />
<el-table-column prop="city" label="City" />
<el-table-column prop="address" label="Address" width="600" />
<el-table-column prop="zip" label="Zip" />
<el-table-column label="Operations">
<template #default="{ row }">
<el-button link type="primary" size="small" @click="handleClick">
编辑
</el-button>
<el-button v-if="row.status === 2" link type="primary" size="small">
删除
</el-button>
</template>
</el-table-column>
</el-pro-table>