Element UI Table 行列拖拽排序功能实现及数据跟随改变的解决方案
Element UI 的 Table 组件本身并不提供行列拖拽排序功能,但我们可以通过自定义一些逻辑来实现这个功能。
首先,我们需要使用 HTML5 的原生拖拽 API 来实现行列拖拽。在 Table 组件的每个单元格中,添加一个 'draggable' 属性,并在 'dragstart' 事件中保存被拖拽的行或列的索引。
<template>
<el-table>
<el-table-column
v-for='(column, index) in columns'
:key='index'
:label='column.label'
:width='column.width'
:draggable='true'
@dragstart='handleDragStart(index)'
@dragover='handleDragOver'
@drop='handleDrop(index)'
></el-table-column>
<el-table-column>
<!-- ... -->
</el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
columns: [
{ label: '列1', width: 100 },
{ label: '列2', width: 100 },
{ label: '列3', width: 100 },
],
};
},
methods: {
handleDragStart(index) {
// 保存被拖拽的列的索引
event.dataTransfer.setData('text/plain', index);
},
handleDragOver(event) {
event.preventDefault();
},
handleDrop(targetIndex) {
const sourceIndex = event.dataTransfer.getData('text/plain');
// 交换列的顺序
const columns = [...this.columns];
[columns[sourceIndex], columns[targetIndex]] = [columns[targetIndex], columns[sourceIndex]];
this.columns = columns;
},
},
};
</script>
上述代码中,我们通过 'dragstart' 事件在被拖拽的列上保存其索引,并在 'drop' 事件中根据拖拽的目标列的索引和被拖拽列的索引交换列的顺序。这样就可以实现列拖动排序的功能。
接下来,我们需要解决列拖动数据不跟随改变的问题。Element UI 的 Table 组件提供了 'sortable' 属性,可以开启列排序功能,但是默认情况下,列的数据不会随着拖动而改变。我们可以通过监听 'sort-change' 事件,手动更新列的数据。
<template>
<el-table :data='tableData' @sort-change='handleSortChange'>
<el-table-column
v-for='(column, index) in columns'
:key='index'
:prop='column.prop'
:label='column.label'
:sortable='true'
:sort-method='column.sortMethod'
:sort-by='column.prop'
@dragstart='handleDragStart(index)'
@dragover='handleDragOver'
@drop='handleDrop(index)'
></el-table-column>
</el-table>
</template>
<script>
export default {
data() {
return {
columns: [
{ prop: 'column1', label: '列1', width: 100, sortMethod: this.sortMethod },
{ prop: 'column2', label: '列2', width: 100, sortMethod: this.sortMethod },
{ prop: 'column3', label: '列3', width: 100, sortMethod: this.sortMethod },
],
tableData: [
{ column1: 'A', column2: 'B', column3: 'C' },
{ column1: 'D', column2: 'E', column3: 'F' },
{ column1: 'G', column2: 'H', column3: 'I' },
],
};
},
methods: {
handleSortChange({ column, prop, order }) {
// 更新列的排序方式和数据
const columns = [...this.columns];
const columnIndex = columns.findIndex((c) => c.prop === prop);
columns[columnIndex].order = order;
this.columns = columns;
// 更新表格数据的排序
this.tableData.sort(this.sortMethod);
},
sortMethod(a, b) {
// 根据列的排序方式对表格数据进行排序
const column = this.columns.find((c) => c.prop === this.orderBy);
if (column && column.order === 'ascending') {
return a[column.prop].localeCompare(b[column.prop]);
} else {
return b[column.prop].localeCompare(a[column.prop]);
}
},
handleDragStart(index) {
// 保存被拖拽的列的索引
event.dataTransfer.setData('text/plain', index);
},
handleDragOver(event) {
event.preventDefault();
},
handleDrop(targetIndex) {
const sourceIndex = event.dataTransfer.getData('text/plain');
// 交换列的顺序
const columns = [...this.columns];
[columns[sourceIndex], columns[targetIndex]] = [columns[targetIndex], columns[sourceIndex]];
this.columns = columns;
},
},
};
</script>
上述代码中,我们监听了 'sort-change' 事件,并在该事件中更新列的排序方式和数据,并手动调用 'sortMethod' 方法对表格数据进行排序。这样就可以实现列拖动排序后数据跟随改变的功能。
需要注意的是,列的拖拽排序功能和列排序功能会相互影响,需要在代码中进行适当的处理,以避免冲突。另外,由于表格数据是通过 JavaScript 数组进行排序的,所以对于自定义的数据类型,需要在 'sortMethod' 方法中进行适当的处理。
原文地址: https://www.cveoy.top/t/topic/qtae 著作权归作者所有。请勿转载和采集!