需求背景:
要求在对话框中,展示的动态表格数据可以进行拖拽排序。(vue2+ElementUI)
问题描述:
1:不是整个进行拖拽排序,只在排序这一列拖动才可以。
2:拖拽过后数据错乱,明明拖动了,但是对应的顺序没有变化,即顺序为3拖拽到1的位置,正确顺序还是1、2、3......,错误顺序为:3、2、1、4......
示例图:
问题解释:
1.指定行拖拽实现,在排序这一列给了一个类<i class="el-icon-rank drag-handle" />,更改的时候指定带有drag-handle类的元素作为拖拽手柄handle: '.drag-handle', 参考了http://t.csdnimg.cn/hV2EE 。相关资料: sortablejs (Sortable.js中文网)。
相关代码如下:
安装 sortablejs
:
npm install sortablejs --save
在 Vue 组件中使用 sortablejs
:
<template>
<div>
<div ref="sortableList">
<el-table
:data="tableData"
style="width: 100%"
row-key="record.id"
>
<el-table-column
prop="name"
label="Name"
></el-table-column>
<el-table-column
prop="sortNum"
label="顺序"
></el-table-column>
<el-table-column label="排序" align="center">
<i class="el-icon-rank drag-handle" />
</el-table-column>
<!-- 其他列 -->
</el-table>
</div>
</div>
</template>
<script>
import Sortable from 'sortablejs';
export default {
data() {
return {
tableData: [
{ id: 1, name: 'John', sortNum: 1 },
{ id: 2, name: 'Doe', sortNum: 2 },
// 其他行数据
],
};
},
mounted() {
this.initSortable();
},
methods: {
initSortable() {
const sortableList = new Sortable(this.$refs.sortableList, {
animation: 150,
handle: '.drag-handle', // 指定带有drag-handle类的元素作为拖拽手柄
onEnd: this.onSortEnd,
});
},
onSortEnd(evt) {
// 拖拽结束时的处理逻辑
console.log('Drag ended', evt);
// 在这里可以更新你的数据,以反映新的顺序
var iList = JSON.parse(JSON.stringify(this.tableData))
this.tableData = []
var movedRow = iList[evt.oldIndex]
iList.splice(evt.oldIndex, 1)
iList.splice(evt.newIndex, 0, movedRow)
iList.forEach((item, index) => {
item.sortNum = index + 1
})
this.$set(this, 'tableData', JSON.parse(JSON.stringify(iList)))
},
},
};
</script>
2.出现数据错乱的主要原因就是row-key='id',每一行的id都是唯一且不会重复的,若没有id可以用Math.round()随机数去代替减少重复率。因为我数据都没有id,参考使用Math.round()随机数去代替减少重复率,还是会出现重复的情况,因此又换用了++的方式。
import { dataList } from '@/api/baseData/dataListApi'
let uniqueId = 0
dataList(params).then((response) => {
var iList1 = JSON.parse(JSON.stringify(response.data))
// 设置sortNum字段
iList1.forEach((item, index) => {
item.sortNum = index + 1
// Math.random() 函数的输出是伪随机的,可能会在不同的行上生成相同的值
// item.myId = parseInt(Math.random() * Math.random() * 10000)
item.myId = this.assignUniqueId()
})
this.$set(this, 'proData', iList1)
this.listLoading = false
})
.catch(() => {
this.listLoading = false
})
.finally((_) => {
this.listLoading = false
// 在数据加载完成后,初始化拖拽功能
this.initDragAndDrop()
})
assignUniqueId() {
return ++uniqueId
},
则对应的:row-key就换成了如下形式。
:row-key="(record) => record.id ? record.id : record.myId"