1、引入依赖 sortablejs
npm install sortable.js --save
2、在mounted() 函数中分别引入两个自定义的方法 , 分别是行和列的拖动
贴一下这两个方法,拖动行方法
dragSort() {
let that = this;
// 首先获取需要拖拽的dom节点
const el1 = document.querySelectorAll('.el-table__body-wrapper')[0].querySelectorAll('table > tbody')[0];
Sortable.create(el1, {
disabled: false, // 是否开启拖拽
ghostClass: 'sortable-ghost', //拖拽样式
animation: 150, // 拖拽延时,效果更好看
group: { // 是否开启跨表拖拽
pull: false,
put: false
},
onEnd: (e) => { // 这里主要进行数据的处理,拖拽实际并不会改变绑定数据的顺序,这里需要自己做数据的顺序更改
}
});
}
拖动列方法
//列拖拽
columnDrop() {
const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
this.sortable = Sortable.create(wrapperTr, {
animation: 180,
delay: 0,
onEnd: evt => {
if(evt.oldIndex===evt.newIndex) return;
const oldItem = this.columnsConfig[evt.oldIndex];
const newItem = this.columnsConfig[evt.newIndex];
this.$set(this.columnsConfig,evt.newIndex,oldItem);
this.$set(this.columnsConfig,evt.oldIndex,newItem);
}
})
},
2.1、这里值得注意一下就是拖动列这里卡了我很久,原因是因为表头数据是改变了,列表的数据也改变了,但是表头视图不更新,原因是因为:在自定义表头的时候,由于是用的v-for循环生成的,因此会给每个循环体一个固定的key,导致数据频繁异步更新时,因为这个key没有变,所以el-table觉得表头数据是没有变化的,因此就只更新了整体表格数据、key值有变化的列的表头
导致出现了这种情况:正常
有问题的:
原因是我生成列的时候key绑定了固定值
解决:
建议key不要使用Math.random,因为这样会引起每次都会去刷新,从而造成资源的浪费,这里提供一个做法就是:key的值可以使用id,每当移动列的时候,监听回调函数(即下方columnDrop函数),就把两个列的key的值重新生成一个新的,这样就不会造成页面列表的抖动,列数据也进行改变了。
3、OK,问题解决。我的是弄成了组件,实现自定义表头,各位看官可以根据自己的需求弄,现在是贴全部代码:
Html
<template>
<div class="TableDrag">
<el-table
:data="tableDatas"
border
@sort-change="sortMethods"
:header-cell-style="{color: '#333333', fontSize: '16px', backgroundColor: '#F5F7FA'}"
>
<slot name="fixed"></slot>
<el-table-column
v-for="(item,index) in columnsConfig"
:key="index+''+Math.random()"
:sortable="item.sortAble"
:label="item.filedZhName"
:prop="item.filedEnName"
:width="item.width"
:column-key="index.toString()"
:show-overflow-tooltip="true"
align="center"
>
<template slot-scope="scope">
<span
v-if="item['filedDataType']=='text'||item['filedDataType']=='option'||item['filedDataType']=='mutiloption'"
>{{scope.row[item.filedEnName]}}</span>
<el-switch
v-else-if="item['filedDataType']=='slots'"
v-model="scope.row[item.filedEnName]"
active-color="#4B7DF6"
inactive-color="#C0C4CC"
on-change="viewGoods(scope.row)"
></el-switch>
<el-popover placement="right" trigger="click" v-if="item['filedDataType']=='zuocao'">
<div class="items">离职</div>
<div class="items">调动</div>
<div class="items">删除</div>
<div slot="reference" style="cursor: pointer;">...{{scope.row.undefined}}</div>
</el-popover>
</template>
</el-table-column>
</el-table>
</div>
</template>
JS
<script>
import Sortable from 'sortablejs';
export default {
props:{
columnsConfig:{ //表头
type:Array,
default:()=>{
return [];
}
},
tableDatas:{ //数据
type:Array,
default:()=>{
return [];
}
}
},
data(){
return{
}
},
mounted(){
this.dragSort();
this.columnDrop();
},
methods:{
//行拖拽
dragSort() {
let that = this;
// 首先获取需要拖拽的dom节点
const el1 = document.querySelectorAll('.el-table__body-wrapper')[0].querySelectorAll('table > tbody')[0];
Sortable.create(el1, {
disabled: false, // 是否开启拖拽
ghostClass: 'sortable-ghost', //拖拽样式
animation: 150, // 拖拽延时,效果更好看
group: { // 是否开启跨表拖拽
pull: false,
put: false
},
onEnd: (e) => { // 这里主要进行数据的处理,拖拽实际并不会改变绑定数据的顺序,这里需要自己做数据的顺序更改
}
});
},
//列拖拽
columnDrop() {
const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
this.sortable = Sortable.create(wrapperTr, {
animation: 180,
delay: 0,
onEnd: evt => {
if(evt.oldIndex===evt.newIndex) return;
const oldItem = this.columnsConfig[evt.oldIndex];
const newItem = this.columnsConfig[evt.newIndex];
this.$set(this.columnsConfig,evt.newIndex,oldItem);
this.$set(this.columnsConfig,evt.oldIndex,newItem);
}
})
},
// 排序的方法
sortMethods(type) {
console.log(type);
},
}
};
data:
columnsConfig: [
{
filedEnName: "names",
filedDataType: "text",
filedZhName: "姓名",
closAble: false,
sortAble: true
},
{
filedDataType: "text",
filedEnName: "telphone",
filedZhName: "手机号码",
closAble: true,//是否可以关闭
sortAble: true,//是否可以排序
},
{
filedEnName: "zhanghao",
filedDataType: "text",
filedZhName: "账号",
closAble: true,
sortAble: false
},
{
filedEnName: "status",
filedDataType: "slots",
filedZhName: "账号状态",
closAble: true,
sortAble: false
},
{
filedEnName: "email",
filedDataType: "text",
filedZhName: "工作邮箱",
closAble: true,
sortAble: true
},
{
filedEnName: "ruzhiriqi",
filedDataType: "text",
filedZhName: "入职日期",
closAble: true,
sortAble: false
},
{
filedEnName: "zuocao",
filedDataType: "zuocao",
filedZhName: "操作",
closAble: true,
sortAble: false
}
],
tableDatas:[
{
id:0,
names:"范德萨发大水",
telphone:"1245488",
zhanghao:"法大师傅",
status:true,
email:"223232",
ruzhiriqi:"2020-06-05"
},
{
id:1,
names:"范德萨发大水3333",
telphone:"1245488",
zhanghao:"法大师傅",
status:false,
email:"223232",
ruzhiriqi:"2020-06-05"
},
{
id:2,
names:"范德萨发大水111",
telphone:"1245488",
zhanghao:"法大师傅",
status:true,
email:"223232",
ruzhiriqi:"2020-06-05"
}
]
style:
.w-table {
::v-deep .el-table .darg_start {
background-color: #f3f3f3;
}
.sortable-ghost {
opacity: 0.4;
background-color: #c1c1c1;
}
//表头高度
::v-deep .el-table th, .el-table tr{
background-color: none;
height: 56px;
}
//td字体和颜色大小
::v-deep .el-table{
td{
font-size: 14px;
color: #666666;
}
}
}