vue3+element-plus 使用Sortable实现table拖拽排序
1.1
npm install sortablejs --save // 安装也可使用yarn
1.2 在需要的页面中引入
import Sortable from "sortablejs"; // 安装也可使用yarn
1.3 具体使用
el-table中配置 给个row-key,且必须是唯一的,比如ID,否则会出现排序不对的情况
<el-table
ref="dragTable"
:data="cityConfigList"
border
row-key="CityCode"
</el-table>
在setup()中编写行拖拽的实现方法,具体逻辑是创建一个Sortable的实例,将需要拖拽的元素给到Sortable实例,进行需要的配置,然后在拖拽结束的方法onEnd()中实现改变排序的逻辑(需要在dom后去调用,获取列表后.then里面也可以)。
// 表格行拖拽
const rowDrop = () => {
let tbody = document.querySelector(".el-table__body-wrapper tbody");
Sortable.create(tbody, {
// or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }
group: {
name: "words",
pull: true,
put: true,
},
animation: 150, // ms, number 单位:ms,定义排序动画的时间
onAdd: function (evt: any) {
// 拖拽时候添加有新的节点的时候发生该事件
console.log("onAdd.foo:", [evt.item, evt.from]);
},
onUpdate: function (evt: any) {
// 拖拽更新节点位置发生该事件
console.log("onUpdate.foo:", [evt.item, evt.from]);
},
onRemove: function (evt: any) {
// 删除拖拽节点的时候促发该事件
console.log("onRemove.foo:", [evt.item, evt.from]);
},
onStart: function (evt: any) {
// 开始拖拽出发该函数
console.log("onStart.foo:", [evt.item, evt.from]);
},
onSort: function (evt: any) {
// 发生排序发生该事件
console.log("onUpdate.foo:", [evt.item, evt.from]);
},
onEnd(evt: any) {
// 结束拖拽
console.log("结束表格拖拽", evt);
// 如果拖拽结束后顺序发生了变化,则对数据进行修改
if (evt.oldIndex !== evt.newIndex) {
let currRow = fieldOptions.value.splice(evt.oldIndex, 1)[0];
fieldOptions.value.splice(evt.newIndex, 0, currRow);
// 将排序后的ID抽离成数组传给后端
let optIDs: string[] = [];
fieldOptions.value.forEach((item) => {
optIDs.push(item.ID);
});
const params = {
Params: {
SpaceID: spaceID.value,
LaunchID: launchID.value,
OptIDs: optIDs,
},
Options: {
APIServer: apiServer,
},
};
// 发送改变顺序的请求
store.commit("doRequest");
spaceService.OrderOptions(params).then((res: any) => {
store.commit("deResponse");
if (res.Status === 0) {
console.log("表格顺序修改成功");
} else {
ElMessage({
showClose: true,
message: res.ErrorMessage,
type: "error",
duration: 10000,
});
}
});
}
},
});
};
如果需要加拖拽图标配置handle添加了 .drag-handler
const initSortable = () => {
console.log(dragTable.value)
const tbody = dragTable.value.$el.querySelector('.el-table__body-wrapper tbody')
console.log(tbody)
Sortable.create(tbody, {
// or { name: "...", pull: [true, false, 'clone', array], put: [true, false, array] }
ghostClass: 'sortable-ghost', // Class name for the drop placeholder,
handle: '.drag-handler',
animation: 150, // ms, number 单位:ms,定义排序动画的时间
setData: function (dataTransfer) {
// to avoid Firefox bug
// Detail see : https://github.com/RubaXa/Sortable/issues/1012
dataTransfer.setData('Text', '')
},
onEnd(evt) {
// 结束拖拽
console.log('结束表格拖拽', evt)
// 如果拖拽结束后顺序发生了变化,则对数据进行修改
if (evt.oldIndex !== evt.newIndex) {
let currRow = cityConfigList.value.splice(evt.oldIndex, 1)[0]
cityConfigList.value.splice(evt.newIndex, 0, currRow)
}
}
})
}
页面代码里面需要安装@element-plus/icons-vue
# NPM
$ npm install @element-plus/icons-vue
# Yarn
$ yarn add @element-plus/icons-vue
# pnpm
$ pnpm install @element-plus/icons-vue
<el-table-column label="拖拽" align="center" width="50px">
<div class="drag-handler">
<el-icon :size="20" style="cursor: pointer">
<Rank></Rank>
</el-icon>
</div>
</el-table-column>
<script setup>
import { Rank } from '@element-plus/icons-vue'
</script>