1. 安装拖拽插件
npm i sortablejs
2. 行拖拽示例代码
<template>
<vxe-grid class="sortable-row-demo" ref="xGridTable" v-bind="options">
<template #dragable_default>
<span class="drag-btn">
<i class="vxe-icon-send"></i>
</span>
</template>
</vxe-grid>
</template>
<script>
import Sortable from 'sortablejs';
export default {
name: 'sortTable',
components: {},
props: {},
data() {
return {
sortable: null,
options: {
border: true,
resizable: true,
rowConfig: { useKey: true }, //非常重要!!!
data: [
{ id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: '0', sex2: ['0'], num1: 40, age: 28, address: 'Shenzhen', date12: '', date13: '' },
{ id: 10002, name: 'Test2', nickname: 'T2', role: 'Designer', sex: '1', sex2: ['0', '1'], num1: 44, age: 22, address: 'Guangzhou', date12: '', date13: '2020-08-20' },
{ id: 10003, name: 'Test3', nickname: 'T3', role: 'Test', sex: '0', sex2: ['1'], num1: 200, age: 32, address: 'test abc', date12: '2020-09-10', date13: '' },
{ id: 10004, name: 'Test4', nickname: 'T4', role: 'Designer', sex: '1', sex2: ['1'], num1: 30, age: 23, address: 'Shenzhen', date12: '', date13: '2020-12-04' },
{ id: 10005, name: 'Test5', nickname: 'T5', role: 'Develop', sex: '0', sex2: ['1', '0'], num1: 20, age: 30, address: 'Shanghai', date12: '2020-09-20', date13: '' },
{ id: 10006, name: 'Test6', nickname: 'T6', role: 'Designer', sex: '1', sex2: ['0'], num1: 10, age: 21, address: 'Shenzhen', date12: '', date13: '' },
{ id: 10007, name: 'Test7', nickname: 'T7', role: 'Develop', sex: '0', sex2: ['0'], num1: 5, age: 29, address: 'test abc', date12: '2020-01-02', date13: '2020-09-20' },
{ id: 10008, name: 'Test8', nickname: 'T8', role: 'PM', sex: '1', sex2: ['0'], num1: 2, age: 35, address: 'Shenzhen', date12: '', date13: '' }
],
columns: [
{
title: '',
fixed: 'left',
width: 50,
align: 'center',
slots: {
default: 'dragable_default'
}
},
{ type: 'radio', width: 50 },
{ type: 'seq', width: 60 },
{ field: 'name', title: 'Name' },
{ field: 'nickname', title: 'Nickname' },
{ field: 'role', title: 'Role' },
{ field: 'address', title: 'Address', showOverflow: true }
]
}
};
},
computed: {},
created() {
this.rowDrop();
},
beforeDestroy() {
if (this.sortable) {
this.sortable.destroy();
}
},
mounted() {},
destroyed() {},
methods: {
rowDrop() {
this.$nextTick(() => {
const xGTable = this.$refs.xGridTable;
this.sortable = Sortable.create(xGTable.$el.querySelector('.body--wrapper>.vxe-table--body tbody'), {
handle: '.drag-btn',
onEnd: ({ newIndex, oldIndex }) => {
const currRow = this.options.data.splice(oldIndex, 1)[0];
this.options.data.splice(newIndex, 0, currRow);
this.$nextTick(() => {
console.log(this.$refs.xGridTable.getTableData().tableData.map(row => row.name));
});
}
});
});
}
}
};
</script>
<style lang="scss" scoped>
.alert-message {
height: 40px;
display: flex;
align-items: center;
margin: 10px 0;
border-radius: 4px;
background-color: #e6f7ff;
border: 1px solid #91d5ff;
}
.alert-message-icon {
width: 30px;
text-align: center;
color: #409eff;
margin-right: 8px;
}
.alert-message-content {
flex-grow: 1;
padding-right: 20px;
}
</style>
<style>
.sortable-row-demo .drag-btn {
cursor: move;
font-size: 12px;
}
.sortable-row-demo .vxe-body--row.sortable-ghost,
.sortable-row-demo .vxe-body--row.sortable-chosen {
background-color: #dfecfb;
}
</style>
参考地址: vxetable.cn/other3/#/ta…
3. 列拖拽示例代码
<template>
<vxe-grid ref="xGrid" v-bind="gridOptions"></vxe-grid>
</template>
<script>
import Sortable from 'sortablejs';
import VXETable from 'vxe-table';
export default {
data() {
return {
gridOptions: {
border: true,
showFooter: true,
class: 'sortable-column-demo',
columnConfig: {
useKey: true,
minWidth: 200
},
scrollX: {
enabled: false
},
footerMethod: this.footerMethod,
toolbarConfig: {
custom: true
},
columns: [
{ field: 'name', title: 'Name', fixed: 'left', width: 300 },
{ field: 'nickname', title: 'Nickname' },
{ field: 'role', title: 'Role' },
{ field: 'sex', title: 'Sex' },
{ field: 'age', title: 'Age' },
{ field: 'date3', title: 'Date' },
{ field: 'address', title: 'Address', width: 200, fixed: 'right', showOverflow: true }
],
data: [
{ id: 10001, name: 'Test1', nickname: 'T1', role: 'Develop', sex: 'Man', age: 28, address: 'Shenzhen' },
{ id: 10002, name: 'Test2', nickname: 'T2', role: 'Test', sex: 'Women', age: 22, address: 'Guangzhou' },
{ id: 10003, name: 'Test3', nickname: 'T3', role: 'PM', sex: 'Man', age: 32, address: 'Shanghai' },
{ id: 10004, name: 'Test4', nickname: 'T4', role: 'Designer', sex: 'Women', age: 23, address: 'Shenzhen' },
{ id: 10005, name: 'Test5', nickname: 'T5', role: 'Develop', sex: 'Women', age: 30, address: 'Shanghai' }
]
}
};
},
created() {
this.columnDrop();
},
beforeDestroy() {
if (this.sortable) {
this.sortable.destroy();
}
},
methods: {
meanNum(list, field) {
let count = 0;
list.forEach(item => {
count += Number(item[field]);
});
return count / list.length;
},
sumNum(list, field) {
let count = 0;
list.forEach(item => {
count += Number(item[field]);
});
return count;
},
footerMethod({ columns, data }) {
return [
columns.map((column, columnIndex) => {
if (columnIndex === 0) {
return '平均';
}
if (['age', 'sex'].includes(column.property)) {
return this.meanNum(data, column.property);
}
return null;
}),
columns.map((column, columnIndex) => {
if (columnIndex === 0) {
return '和值';
}
if (['age', 'sex'].includes(column.property)) {
return this.sumNum(data, column.property);
}
return null;
})
];
},
columnDrop() {
this.$nextTick(() => {
const $table = this.$refs.xGrid;
this.sortable = Sortable.create($table.$el.querySelector('.body--wrapper>.vxe-table--header .vxe-header--row'), {
handle: '.vxe-header--column',
onEnd: ({ item, newIndex, oldIndex }) => {
const { fullColumn, tableColumn } = $table.getTableColumn();
const targetThElem = item;
const wrapperElem = targetThElem.parentNode;
const newColumn = fullColumn[newIndex];
if (newColumn.fixed) {
const oldThElem = wrapperElem.children[oldIndex];
// 错误的移动
if (newIndex > oldIndex) {
wrapperElem.insertBefore(targetThElem, oldThElem);
} else {
wrapperElem.insertBefore(targetThElem, oldThElem ? oldThElem.nextElementSibling : oldThElem);
}
VXETable.modal.message({ content: '固定列不允许拖动,即将还原操作!', status: 'error' });
return;
}
// 获取列索引 columnIndex > fullColumn
const oldColumnIndex = $table.getColumnIndex(tableColumn[oldIndex]);
const newColumnIndex = $table.getColumnIndex(tableColumn[newIndex]);
// 移动到目标列
const currRow = fullColumn.splice(oldColumnIndex, 1)[0];
fullColumn.splice(newColumnIndex, 0, currRow);
$table.loadColumn(fullColumn);
}
});
});
}
}
};
</script>
<style>
.sortable-column-demo .vxe-header--row .vxe-header--column.sortable-ghost,
.sortable-column-demo .vxe-header--row .vxe-header--column.sortable-chosen {
background-color: #dfecfb;
}
.sortable-column-demo .vxe-header--row .vxe-header--column.col--fixed {
cursor: no-drop;
}
</style>