预览效果
功能描述
最近在做一个功能,要求是鼠标拖动表格头,实现表格列的排序。刚开始去elementUI看了下官方文档,发现没有这个功能,所以百度搜了一下,发现有一个插件可以实现: sortablejs
代码实现
安装插件
npm install sortablejs --save
代码部分
util文件
//移动数组元素至某个指定位置
export function moveArr(arr, newIndex, oldIndex) {
// console.log('arr', arr, oldIndex, newIndex);
arr.splice(newIndex, 0, arr.splice(oldIndex, 1)[0])
/** splice 会更改原来数组的数据 */
/** list.splice(oldIndex, 1)[0] 删除旧数据位置返回删除的数据 */
/** list.splice(newIndex, 0, old) 相当于把删除的旧数据插入到新的位置上去 */
}
组件
<template>
<el-table :data="tableData" @sort-change="sortMethods" @selection-change="handleSelectionChange" border >
<el-table-column type="index" label="序号" width="55" align="center"></el-table-column>
<el-table-column type="selection" label="勾选"></el-table-column>
<el-table-column
v-for="(item, index) in tableHeader"
:label="item.label"
:type="item.type"
:width="item.width"
:sortable="item.sort"
:key="index + '' + Math.random()"
show-overflow-tooltip
align="center"
>
<!-- 自定义表格头部插槽 -->
<!-- <template #header="{column, $index }">
<span>{{ column }}}</span>
</template> -->
<!-- 表格体内容显示插槽 -->
<template #default="{ row, column, $index }">
<span v-if="item['showType'] == 'text'">
{{ row[item.prop] }}
</span>
<span v-else-if="item['showType'] == 'sex'">
{{ row.sex === "F" ? "女" : "男" }}
</span>
<span v-else-if="item['showType'] == 'status'">
{{ row.status == "1" ? "开心" : "郁闷" }}
</span>
</template>
</el-table-column>
</el-table>
</template>
<script>
//导入定义的方法
import { moveArr } from '@/utils/util'
// 导入插件
import Sortable from 'sortablejs';
export default {
name: "zan",
data() {
return {
//表格头
tableHeader:[
{
label:'姓名',
prop:'name',
showType:'text',
width:'',
sort:false
},
{
label:'年龄',
prop:'age',
showType:'text',
width:'',
sort:true
},
{
label:'爱好',
prop:'hobby',
showType:'text',
width:'',
sort:false
},
{
label:'电话',
prop:'phone',
showType:'text',
width:'',
sort:true
},
{
label:'性别',
prop:'sex',
showType:'sex',
width:'',
sort:false
},
{
label:'心情',
prop:'status',
showType:'status',
width:'',
sort:false
},
],
//表格数据
tableData:[
{
name:'jack',
age:18,
hobby:'篮球',
phone:1239742,
sex:'M',
status:0
},
{
name:'娜娜',
age:16,
hobby:'跳',
phone:13745134,
sex:'F',
status:1
},
{
name:'你干嘛~',
age:24,
hobby:'rap',
phone:5201413,
sex:'M',
status:1
},
],
};
},
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) => {
// 这里主要进行数据的处理,拖拽实际并不会改变绑定数据的顺序,这里需要自己做数据的顺序更改
console.log(e);
}
});
},
//列拖拽
columnDrop() {
const wrapperTr = document.querySelector('.el-table__header-wrapper tr')
this.sortable = Sortable.create(wrapperTr, {
animation: 180,
delay: 0,
onEnd: evt => {
console.log(evt.oldIndex,evt.newIndex);
if (evt.oldIndex === evt.newIndex) return;
//表头排序
// 这里-2是因为表格头前两列是上面HTML中自己定义的序号列和勾选列,tableHeader数据中没有定义该两列,所以操作数组的时候要排除掉这两项
moveArr(this.tableHeader, evt.newIndex-2, evt.oldIndex-2)
// const oldItem = this.tableHeader[evt.oldIndex];
// const newItem = this.tableHeader[evt.newIndex];
// this.$set(this.columnsConfig, evt.newIndex, oldItem);
// this.$set(this.columnsConfig, evt.oldIndex, newItem);
}
})
},
// 列数据排序
sortMethods(type) {
console.log(type);
},
//勾选的数据
handleSelectionChange(row) {
console.log(row);
},
},
};
</script>
<style scoped>
</style>