使用sortablejs 实现el-table拖拽排序
本质上还是js的拖拽API,也可以使用原生的drag系列函数(dragstart、drag、dragend、dragover、drop、dragleave)实现。这里介绍使用sortablejs 插件快速实现拖拽排序这个功能。
1. 安装sortablejs
官网(https://sortablejs.com)提供了各种环境的安装方式,这里使用前端最常见的npm包安装
npm install sortablejs --save
2. 使用
在项目中引入插件
import Sortable from ‘sortablejs’
在mounted生命周期函数中创建对象实例
一定要在nextTick里面去做调用,否则有可能不生效
mounted(){
this.$nextTick(() => {
this.initSortTable();
});
}
在methods中创建initSortTable 函数
initSortTable() {
// 获取 el-table
const tableTag = this.$refs['tableView'].$el;
// 获取 tbody 节点
const elTbody = tableTag.querySelectorAll('.el-table__body-wrapper > table > tbody')[0];
new Sortable(elTbody, {
animation: 150, // 拖拽时的动画速度,单位为毫秒
handle: '.el-table__row', // 拖拽的手柄元素,这里使用表格的行作为手柄
onEnd: (evt) => {
this.dragSort(evt);// 拖拽结束时的回调函数
},
});
},
到此基本已经实现可以拖拽表格的行进行移动排序。
当然还是需要结合后端实现排序的记录。可以在这里的dragSort中调用后端接口进行结果保存。
dragSort(event) {
//前端排序数据处理
const movedItem = this.tableData.splice(event.oldIndex, 1)[0];
this.tableData.splice(event.newIndex, 0, movedItem);
this.$forceUpdate(); // 强制更新组件
//调用后端接口
},
3. 优化
3. 1 可拖拽范围
目前为止,可以实现整个table行拖拽的时候进行排序,但是也会有写问题,当前行拖拽的范围有点大,可能会有很多误触的情况,
此时只需要修改Sortable参数的handle 即可。可以在表格行中添加一个按钮,将这个按钮设置为handle。这样就可以实现将拖拽响应绑定在一个按钮的范围。
new Sortable(elTbody, {
animation: 150, // 拖拽时的动画速度,单位为毫秒
handle: '.drag-item', // 拖拽的手柄元素,这里使用表格的行作为手柄
onEnd: (evt) => {
this.dragSort(evt); // 拖拽结束时的回调函数
},
});
3.2 固定表格列造成的拖拽数据串行
我们经常会将表格的最后一行进行固定,例如:
<el-table-column label="操作" width="240" fixed="right">
<template slot-scope="scope">
<el-button size="mini" plain @click="$refs.editRef.openDialog(scope.row.uuid, true)">修改</el-button>
<el-button size="mini" plain @click="$refs.editRef.openDialog(scope.row.uuid, false)">查看</el-button>
<el-button type="warning" size="mini" plain @click="deleteItem(scope.row)">删除</el-button>
<el-button size="mini" icon="el-icon-d-caret" plain class="drag-item">排序</el-button>
</template>
</el-table-column>
此时拖着排序按钮会造成scope中的数据与所对应的行错乱,这是因为在el-table组件中,fixed中的内容并不会与表格其他内容创建在同一行中,而是创建了多个表格。如下图:
所以我们在获取table节点的时候就不能使用前面的数据table,而是使用后面的操作单元表格el-table__fixed-body-wrapper
initSortTable() {
// 获取 el-table
const tableTag = this.$refs['tableView'].$el;
// 获取 tbody 节点
const elTbody = tableTag.querySelectorAll('.el-table__fixed-body-wrapper > table > tbody')[0];
new Sortable(elTbody, {
animation: 150, // 拖拽时的动画速度,单位为毫秒
handle: '.drag-item', // 拖拽的手柄元素,这里使用表格的行作为手柄
onEnd: (evt) => {
this.dragSort(evt);
}, // 拖拽结束时的回调函数
});
},
以下为园子小伙伴指正意见
使用sortablejs 实现el-table拖拽排序
dragSort(event) {
//前端排序数据处理
const movedItem = this.tableData.splice(event.oldIndex, 1)[0];
this.tableData.splice(event.newIndex, 0, movedItem);
this.$forceUpdate(); // 强制更新组件
//调用后端接口
},
方法的时候会出现数据错乱 可以使用下面这个方法来避免
const oldRow = this.tableData[event.oldIndex]
this.tableData[event.oldIndex] = this.tableData[event.newIndex]
this.tableData[event.newIndex] = oldRow
这种调换顺序的方式不改变原来绑定的table数组数据时没有问题
如果要改变el-table中的sort等顺序可以在表格上面添加
row-key="id"
给每个行指定一个key
然后更新那里使用$set方法
//这里使用$set方式是告诉el-table 绑定的数据值发生变化,需要重新渲染
this.$set(this.tableData, event.oldIndex, this.tableData[event.newIndex])
this.$set(this.tableData, event.newIndex, oldRow)
this.$forceUpdate() // 强制更新组件
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)