mirror of https://github.com/ElemeFE/element
Merge pull request #691 from furybean/table-remote-sort
Table: add column remote/custom sort.pull/690/head
commit
8e60aff175
|
@ -918,6 +918,7 @@
|
||||||
| cell-mouse-leave | 当单元格 hover 退出时会触发该事件 | row, column, cell, event |
|
| cell-mouse-leave | 当单元格 hover 退出时会触发该事件 | row, column, cell, event |
|
||||||
| cell-click | 当某个单元格被点击时会触发该事件 | row, column, cell, event |
|
| cell-click | 当某个单元格被点击时会触发该事件 | row, column, cell, event |
|
||||||
| row-click | 当某一行被点击时会触发该事件 | row, event |
|
| row-click | 当某一行被点击时会触发该事件 | row, event |
|
||||||
|
| sort-change | 当表格的排序条件发生变化的时候会触发该事件 | { column, prop, order } |
|
||||||
|
|
||||||
### Table Methods
|
### Table Methods
|
||||||
| 方法名 | 说明 | 参数 |
|
| 方法名 | 说明 | 参数 |
|
||||||
|
@ -931,7 +932,8 @@
|
||||||
| prop | 对应列内容的字段名,也可以使用 property 属性 | string | — | — |
|
| prop | 对应列内容的字段名,也可以使用 property 属性 | string | — | — |
|
||||||
| width | 对应列的宽度 | string | — | — |
|
| width | 对应列的宽度 | string | — | — |
|
||||||
| fixed | 列是否固定在左侧或者右侧,true 表示固定在左侧 | string, boolean | true, left, right | - |
|
| fixed | 列是否固定在左侧或者右侧,true 表示固定在左侧 | string, boolean | true, left, right | - |
|
||||||
| sortable | 对应列是否可以排序 | boolean | — | false |
|
| sortable | 对应列是否可以排序,如果设置为 'custom',则代表用户希望远程排序,需要监听 Table 的 sort-change 事件 | boolean, string | true, false, 'custom' | false |
|
||||||
|
| sort-method | 对数据进行排序的时候使用的方法,仅当 sortable 设置为 true 的时候有效 | Function(a, b) | - | - |
|
||||||
| resizable | 对应列是否可以通过拖动改变宽度(如果需要在 el-table 上设置 border 属性为真) | boolean | — | true |
|
| resizable | 对应列是否可以通过拖动改变宽度(如果需要在 el-table 上设置 border 属性为真) | boolean | — | true |
|
||||||
| type | 对应列的类型。如果设置了 `selection` 则显示多选框,如果设置了 `index` 则显示该行的索引(从 1 开始计算) | string | selection/index | — |
|
| type | 对应列的类型。如果设置了 `selection` 则显示多选框,如果设置了 `index` 则显示该行的索引(从 1 开始计算) | string | selection/index | — |
|
||||||
| formatter | 用来格式化内容 | Function(row, column) | — | — |
|
| formatter | 用来格式化内容 | Function(row, column) | — | — |
|
||||||
|
|
|
@ -6,19 +6,19 @@ let columnIdSeed = 1;
|
||||||
|
|
||||||
const defaults = {
|
const defaults = {
|
||||||
default: {
|
default: {
|
||||||
direction: ''
|
order: ''
|
||||||
},
|
},
|
||||||
selection: {
|
selection: {
|
||||||
width: 48,
|
width: 48,
|
||||||
minWidth: 48,
|
minWidth: 48,
|
||||||
realWidth: 48,
|
realWidth: 48,
|
||||||
direction: ''
|
order: ''
|
||||||
},
|
},
|
||||||
index: {
|
index: {
|
||||||
width: 48,
|
width: 48,
|
||||||
minWidth: 48,
|
minWidth: 48,
|
||||||
realWidth: 48,
|
realWidth: 48,
|
||||||
direction: ''
|
order: ''
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -48,15 +48,6 @@ const forced = {
|
||||||
return <div>{ $index + 1 }</div>;
|
return <div>{ $index + 1 }</div>;
|
||||||
},
|
},
|
||||||
sortable: false
|
sortable: false
|
||||||
},
|
|
||||||
filter: {
|
|
||||||
headerTemplate: function(h) {
|
|
||||||
return '#';
|
|
||||||
},
|
|
||||||
template: function(h, { row, column }) {
|
|
||||||
return <el-tag type="primary" style="height: 16px; line-height: 16px; min-width: 40px; text-align: center">{ row[column.property] }</el-tag>;
|
|
||||||
},
|
|
||||||
resizable: false
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,9 +89,10 @@ export default {
|
||||||
minWidth: {},
|
minWidth: {},
|
||||||
template: String,
|
template: String,
|
||||||
sortable: {
|
sortable: {
|
||||||
type: Boolean,
|
type: [Boolean, String],
|
||||||
default: false
|
default: false
|
||||||
},
|
},
|
||||||
|
sortMethod: Function,
|
||||||
resizable: {
|
resizable: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: true
|
default: true
|
||||||
|
@ -201,6 +193,7 @@ export default {
|
||||||
isColumnGroup,
|
isColumnGroup,
|
||||||
align: this.align ? 'is-' + this.align : null,
|
align: this.align ? 'is-' + this.align : null,
|
||||||
sortable: this.sortable,
|
sortable: this.sortable,
|
||||||
|
sortMethod: this.sortMethod,
|
||||||
resizable: this.resizable,
|
resizable: this.resizable,
|
||||||
showTooltipWhenOverflow: this.showTooltipWhenOverflow,
|
showTooltipWhenOverflow: this.showTooltipWhenOverflow,
|
||||||
formatter: this.formatter,
|
formatter: this.formatter,
|
||||||
|
|
|
@ -33,7 +33,7 @@ export default {
|
||||||
on-mousemove={ ($event) => this.handleMouseMove($event, column) }
|
on-mousemove={ ($event) => this.handleMouseMove($event, column) }
|
||||||
on-mouseout={ this.handleMouseOut }
|
on-mouseout={ this.handleMouseOut }
|
||||||
on-mousedown={ ($event) => this.handleMouseDown($event, column) }
|
on-mousedown={ ($event) => this.handleMouseDown($event, column) }
|
||||||
class={ [column.id, column.direction, column.align, this.isCellHidden(cellIndex) ? 'hidden' : ''] }>
|
class={ [column.id, column.order, column.align, this.isCellHidden(cellIndex) ? 'hidden' : ''] }>
|
||||||
<div class={ ['cell', column.filteredValue && column.filteredValue.length > 0 ? 'highlight' : ''] }>
|
<div class={ ['cell', column.filteredValue && column.filteredValue.length > 0 ? 'highlight' : ''] }>
|
||||||
{
|
{
|
||||||
column.headerTemplate
|
column.headerTemplate
|
||||||
|
@ -268,26 +268,30 @@ export default {
|
||||||
|
|
||||||
if (!column.sortable) return;
|
if (!column.sortable) return;
|
||||||
|
|
||||||
const sortCondition = this.store.states.sortCondition;
|
const states = this.store.states;
|
||||||
|
let sortProp = states.sortProp;
|
||||||
|
let sortOrder;
|
||||||
|
const sortingColumn = states.sortingColumn;
|
||||||
|
|
||||||
if (sortCondition.column !== column) {
|
if (sortingColumn !== column) {
|
||||||
if (sortCondition.column) {
|
if (sortingColumn) {
|
||||||
sortCondition.column.direction = '';
|
sortingColumn.order = null;
|
||||||
}
|
}
|
||||||
sortCondition.column = column;
|
states.sortingColumn = column;
|
||||||
sortCondition.property = column.property;
|
sortProp = column.property;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!column.direction) {
|
if (!column.order) {
|
||||||
column.direction = 'ascending';
|
sortOrder = column.order = 'ascending';
|
||||||
} else if (column.direction === 'ascending') {
|
} else if (column.order === 'ascending') {
|
||||||
column.direction = 'descending';
|
sortOrder = column.order = 'descending';
|
||||||
} else {
|
} else {
|
||||||
column.direction = '';
|
sortOrder = column.order = null;
|
||||||
sortCondition.column = null;
|
states.sortingColumn = null;
|
||||||
sortCondition.property = null;
|
sortProp = null;
|
||||||
}
|
}
|
||||||
sortCondition.direction = column.direction === 'descending' ? -1 : 1;
|
states.sortProp = sortProp;
|
||||||
|
states.sortOrder = sortOrder;
|
||||||
|
|
||||||
this.store.commit('changeSortCondition');
|
this.store.commit('changeSortCondition');
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,6 +11,14 @@ const getRowIdentity = (row, rowKey) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const sortData = (data, states) => {
|
||||||
|
const sortingColumn = states.sortingColumn;
|
||||||
|
if (!sortingColumn || typeof sortingColumn.sortable === 'string') {
|
||||||
|
return data;
|
||||||
|
}
|
||||||
|
return orderBy(data, states.sortProp, states.sortOrder, sortingColumn.sortMethod);
|
||||||
|
};
|
||||||
|
|
||||||
const TableStore = function(table, initialState = {}) {
|
const TableStore = function(table, initialState = {}) {
|
||||||
if (!table) {
|
if (!table) {
|
||||||
throw new Error('Table is required.');
|
throw new Error('Table is required.');
|
||||||
|
@ -26,11 +34,9 @@ const TableStore = function(table, initialState = {}) {
|
||||||
_data: null,
|
_data: null,
|
||||||
filteredData: null,
|
filteredData: null,
|
||||||
data: null,
|
data: null,
|
||||||
sortCondition: {
|
sortingColumn: null,
|
||||||
column: null,
|
sortProp: null,
|
||||||
property: null,
|
sortOrder: null,
|
||||||
direction: null
|
|
||||||
},
|
|
||||||
isAllSelected: false,
|
isAllSelected: false,
|
||||||
selection: [],
|
selection: [],
|
||||||
reserveSelection: false,
|
reserveSelection: false,
|
||||||
|
@ -52,7 +58,7 @@ TableStore.prototype.mutations = {
|
||||||
if (data && data[0] && typeof data[0].$selected === 'undefined') {
|
if (data && data[0] && typeof data[0].$selected === 'undefined') {
|
||||||
data.forEach((item) => Vue.set(item, '$selected', false));
|
data.forEach((item) => Vue.set(item, '$selected', false));
|
||||||
}
|
}
|
||||||
states.data = orderBy((data || []), states.sortCondition.property, states.sortCondition.direction);
|
states.data = sortData((data || []), states);
|
||||||
|
|
||||||
if (!states.reserveSelection) {
|
if (!states.reserveSelection) {
|
||||||
states.isAllSelected = false;
|
states.isAllSelected = false;
|
||||||
|
@ -82,7 +88,13 @@ TableStore.prototype.mutations = {
|
||||||
},
|
},
|
||||||
|
|
||||||
changeSortCondition(states) {
|
changeSortCondition(states) {
|
||||||
states.data = orderBy((states.filteredData || states._data || []), states.sortCondition.property, states.sortCondition.direction);
|
states.data = sortData((states.filteredData || states._data || []), states);
|
||||||
|
|
||||||
|
this.table.$emit('sort-change', {
|
||||||
|
column: this.states.sortingColumn,
|
||||||
|
prop: this.states.sortProp,
|
||||||
|
order: this.states.sortOrder
|
||||||
|
});
|
||||||
|
|
||||||
Vue.nextTick(() => this.table.updateScrollY());
|
Vue.nextTick(() => this.table.updateScrollY());
|
||||||
},
|
},
|
||||||
|
@ -113,7 +125,7 @@ TableStore.prototype.mutations = {
|
||||||
});
|
});
|
||||||
|
|
||||||
states.filteredData = data;
|
states.filteredData = data;
|
||||||
states.data = orderBy(data, states.sortCondition.property, states.sortCondition.direction);
|
states.data = sortData(data, states);
|
||||||
|
|
||||||
Vue.nextTick(() => this.table.updateScrollY());
|
Vue.nextTick(() => this.table.updateScrollY());
|
||||||
},
|
},
|
||||||
|
|
|
@ -58,14 +58,19 @@ const isObject = function(obj) {
|
||||||
return obj !== null && typeof obj === 'object';
|
return obj !== null && typeof obj === 'object';
|
||||||
};
|
};
|
||||||
|
|
||||||
export const orderBy = function(array, sortKey, reverse) {
|
export const orderBy = function(array, sortKey, reverse, sortMethod) {
|
||||||
|
if (typeof reverse === 'string') {
|
||||||
|
reverse = reverse === 'descending' ? -1 : 1;
|
||||||
|
}
|
||||||
if (!sortKey) {
|
if (!sortKey) {
|
||||||
return array;
|
return array;
|
||||||
}
|
}
|
||||||
const order = (reverse && reverse < 0) ? -1 : 1;
|
const order = (reverse && reverse < 0) ? -1 : 1;
|
||||||
|
|
||||||
// sort on a copy to avoid mutating original array
|
// sort on a copy to avoid mutating original array
|
||||||
return array.slice().sort(function(a, b) {
|
return array.slice().sort(sortMethod ? function(a, b) {
|
||||||
|
return sortMethod(a, b) ? order : -order;
|
||||||
|
} : function(a, b) {
|
||||||
if (sortKey !== '$key') {
|
if (sortKey !== '$key') {
|
||||||
if (isObject(a) && '$value' in a) a = a.$value;
|
if (isObject(a) && '$value' in a) a = a.$value;
|
||||||
if (isObject(b) && '$value' in b) b = b.$value;
|
if (isObject(b) && '$value' in b) b = b.$value;
|
||||||
|
|
Loading…
Reference in New Issue