前言
Element-ui el-table中只有表头的字段排序,并没有拖拽排序。如果需要实现拖拽排序,可以采用SortableJs来实现拖拽排序。
项目需求
- 点击字段排序按钮后进行拖拽排序,第一列由原来的选择框,变为拖拽图标。
- 没点击字段排序按钮,不可进行拖拽操作。
- 选择框,序号,字段名添加
fixed:left,使其固定在左侧。 - 系统自动生成的字段不可拖拽。
- 主键不能和非主键相互拖拽,只能主键和主键相互拖,非主键和非主键相互拖。
- 拖拽结束后,点击保持按钮将整个表格变化后的数据都重新传给后端。
第一步 安装sortablejs
npm install sortablejs --save
第二步 在需要实现表格拖拽的.vue文件中引入
import Sortable from 'sortablejs'
示例:
- 主键不能和非主键相互拖拽
- 非主键和非主键相互拖拽
- 系统自动生成的字段不可拖拽
- 取消或者保持后不可进行拖拽操作
<template>
<el-table
empty-text=" "
ref="dragTable"
row-key="id"
v-loading="table_loading"
:header-cell-style="{ background: '#F2F6FA', color: '#2C3D55', }"
:data="tableData"
style="width: 100%"
class="USN" border
:height="tableHeight"
@selection-change="handleSelectionChange"
:row-class-name="rowClassName" >
<el-table-column type="selection" align="center" width="40" v-if="!sortValue" > </el-table-column>
<el-table-column fixed width="50" v-else align="center">
<template>
<img src="@img/sort.svg" style="width: 12px; height: 12px; padding-right: 4px" />
</template>
</el-table-column>
<el-table-column fixed="left" width="60" label="序号" prop="id">
<template slot-scope="{ row }">
<span>{{ row.$index }}</span> </template>
</el-table-column>
...
</el-table>
</template>
// 开启排序
enableSorting(){
this.fieldOrder = true; // 来控制按钮变取消和保持
this.$refs.smTableList.enableSorting(); //调用子组件的方法
},
// 开启排序
enableSorting() {
this.sortValue = true;
this.disabled = false;
this.setSort();
},
//给每行data.row.initFlag === 1 添加class名字
// initFlag === 1 为系统生成不可拖拽
rowClassName(data) {
if (data.row.initFlag === 1) {
return "rowClassFilter";
}
},
setSort() {
const tableTag = this.$refs.dragTable.$el;
// 字段设置fixed="left"是,绑定一层的话会出现设置fixed的字段无法拖拽
const fixedBodyWrapper = tableTag.querySelector( ".el-table__fixed-body-wrapper table tbody" ); // 绑定fixed这一层的表格
const bodyWrapper = tableTag.querySelector( ".el-table__body-wrapper tbody" );
if (fixedBodyWrapper) {
this.sortable = Sortable.create(fixedBodyWrapper, {
filter: ".rowClassFilter",
onEnd: this.onSortEnd,
//如果className === rowClassFilter 系统自动生成的不可以拖拽
onMove({ related }) {
return related.className.indexOf("rowClassFilter") === -1;
},
sort: this.sortValue,
disabled: this.disabled,
});
}
if (bodyWrapper) {
this.sortable = Sortable.create(bodyWrapper, { filter: ".rowClassFilter",
onEnd: this.onSortEnd,
onMove({ related }) {
return related.className.indexOf("rowClassFilter") === -1;
},
sort: this.sortValue,
disabled: this.disabled,
});
}
},
onSortEnd(evt) {
const { oldIndex, newIndex } = evt;
const movedItem = this.tableData[oldIndex];
const targetItem = this.tableData.length > newIndex ? this.tableData[newIndex] : null; //判断是不是主键
if ( movedItem.primaryKeyFlag !== (targetItem ? targetItem.primaryKeyFlag : false) ) {
this.$message.error("主键和非主键不能相互拖拽");
this.sortable.captureAnimationState(); // 捕获当前动画状态 // 使用DOM操作将项目放回原来的位置
evt.to.removeChild(evt.item);
evt.from.insertBefore(evt.item,
evt.from.children[evt.oldIndex]);
this.sortable.animateAll(); // 应用动画使元素返回原位 return;
}
//数据交换位置
this.tableData.splice(newIndex, 0, this.tableData.splice(oldIndex, 1)[0]);
},
// 拖拽时,选择框的表头隐藏掉
<style>
.dim .el-table__fixed-header-wrapper .el-table__header th:first-child div {
display: none !important;
}
</style>
总结
第一次在这里写笔记,希望对大家有用。工作顺利,工作稳定。
欢迎一键三连哦~
各位,加油!!!