mirror of https://github.com/ElemeFE/element
Table: improve performance (#9426)
* improve table render time in some condition * Update table.vuepull/9566/head
parent
b27f340561
commit
9b9384214b
|
@ -0,0 +1,68 @@
|
||||||
|
export default {
|
||||||
|
created() {
|
||||||
|
this.tableLayout.addObserver(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
destroyed() {
|
||||||
|
this.tableLayout.removeObserver(this);
|
||||||
|
},
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
tableLayout() {
|
||||||
|
let layout = this.layout;
|
||||||
|
if (!layout && this.table) {
|
||||||
|
layout = this.table.layout;
|
||||||
|
}
|
||||||
|
if (!layout) {
|
||||||
|
throw new Error('Can not find table layout.');
|
||||||
|
}
|
||||||
|
return layout;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
mounted() {
|
||||||
|
this.onColumnsChange(this.tableLayout);
|
||||||
|
this.onScrollableChange(this.tableLayout);
|
||||||
|
},
|
||||||
|
|
||||||
|
updated() {
|
||||||
|
if (this.__updated__) return;
|
||||||
|
this.onColumnsChange(this.tableLayout);
|
||||||
|
this.onScrollableChange(this.tableLayout);
|
||||||
|
this.__updated__ = true;
|
||||||
|
},
|
||||||
|
|
||||||
|
methods: {
|
||||||
|
onColumnsChange() {
|
||||||
|
const cols = this.$el.querySelectorAll('colgroup > col');
|
||||||
|
if (!cols.length) return;
|
||||||
|
const flattenColumns = this.tableLayout.getFlattenColumns();
|
||||||
|
const columnsMap = {};
|
||||||
|
flattenColumns.forEach((column) => {
|
||||||
|
columnsMap[column.id] = column;
|
||||||
|
});
|
||||||
|
for (let i = 0, j = cols.length; i < j; i++) {
|
||||||
|
const col = cols[i];
|
||||||
|
const name = col.getAttribute('name');
|
||||||
|
const column = columnsMap[name];
|
||||||
|
if (column) {
|
||||||
|
col.setAttribute('width', column.realWidth || column.width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
onScrollableChange(layout) {
|
||||||
|
const cols = this.$el.querySelectorAll('colgroup > col[name=gutter]');
|
||||||
|
for (let i = 0, j = cols.length; i < j; i++) {
|
||||||
|
const col = cols[i];
|
||||||
|
col.setAttribute('width', layout.scrollY ? layout.gutterWidth : '0');
|
||||||
|
}
|
||||||
|
const ths = this.$el.querySelectorAll('th.gutter');
|
||||||
|
for (let i = 0, j = ths.length; i < j; i++) {
|
||||||
|
const th = ths[i];
|
||||||
|
th.style.width = layout.scrollY ? layout.gutterWidth + 'px' : '0';
|
||||||
|
th.style.display = layout.scrollY ? '' : 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
|
@ -3,8 +3,13 @@ import { hasClass, addClass, removeClass } from 'element-ui/src/utils/dom';
|
||||||
import ElCheckbox from 'element-ui/packages/checkbox';
|
import ElCheckbox from 'element-ui/packages/checkbox';
|
||||||
import ElTooltip from 'element-ui/packages/tooltip';
|
import ElTooltip from 'element-ui/packages/tooltip';
|
||||||
import debounce from 'throttle-debounce/debounce';
|
import debounce from 'throttle-debounce/debounce';
|
||||||
|
import LayoutObserver from './layout-observer';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
name: 'ElTableBody',
|
||||||
|
|
||||||
|
mixins: [LayoutObserver],
|
||||||
|
|
||||||
components: {
|
components: {
|
||||||
ElCheckbox,
|
ElCheckbox,
|
||||||
ElTooltip
|
ElTooltip
|
||||||
|
@ -16,9 +21,6 @@ export default {
|
||||||
},
|
},
|
||||||
stripe: Boolean,
|
stripe: Boolean,
|
||||||
context: {},
|
context: {},
|
||||||
layout: {
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
rowClassName: [String, Function],
|
rowClassName: [String, Function],
|
||||||
rowStyle: [Object, Function],
|
rowStyle: [Object, Function],
|
||||||
fixed: String,
|
fixed: String,
|
||||||
|
@ -35,11 +37,7 @@ export default {
|
||||||
border="0">
|
border="0">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
{
|
{
|
||||||
this._l(this.columns, column =>
|
this._l(this.columns, column => <col name={ column.id } />)
|
||||||
<col
|
|
||||||
name={ column.id }
|
|
||||||
width={ column.realWidth || column.width }
|
|
||||||
/>)
|
|
||||||
}
|
}
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<tbody>
|
<tbody>
|
||||||
|
@ -112,9 +110,6 @@ export default {
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
{
|
|
||||||
!this.fixed && this.layout.scrollY && this.layout.gutterWidth ? <td class="gutter" /> : ''
|
|
||||||
}
|
|
||||||
</tr>,
|
</tr>,
|
||||||
this.store.isRowExpanded(row)
|
this.store.isRowExpanded(row)
|
||||||
? (<tr>
|
? (<tr>
|
||||||
|
@ -344,7 +339,7 @@ export default {
|
||||||
|
|
||||||
if (hasClass(cellChild, 'el-tooltip') && cellChild.scrollWidth > cellChild.offsetWidth && this.$refs.tooltip) {
|
if (hasClass(cellChild, 'el-tooltip') && cellChild.scrollWidth > cellChild.offsetWidth && this.$refs.tooltip) {
|
||||||
const tooltip = this.$refs.tooltip;
|
const tooltip = this.$refs.tooltip;
|
||||||
|
// TODO 会引起整个 Table 的重新渲染,需要优化
|
||||||
this.tooltipContent = cell.textContent || cell.innerText;
|
this.tooltipContent = cell.textContent || cell.innerText;
|
||||||
tooltip.referenceElm = cell;
|
tooltip.referenceElm = cell;
|
||||||
tooltip.$refs.popper && (tooltip.$refs.popper.style.display = 'none');
|
tooltip.$refs.popper && (tooltip.$refs.popper.style.display = 'none');
|
||||||
|
@ -363,7 +358,7 @@ export default {
|
||||||
const cell = getCell(event);
|
const cell = getCell(event);
|
||||||
if (!cell) return;
|
if (!cell) return;
|
||||||
|
|
||||||
const oldHoverState = this.table.hoverState;
|
const oldHoverState = this.table.hoverState || {};
|
||||||
this.table.$emit('cell-mouse-leave', oldHoverState.row, oldHoverState.column, oldHoverState.cell, event);
|
this.table.$emit('cell-mouse-leave', oldHoverState.row, oldHoverState.column, oldHoverState.cell, event);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -116,6 +116,26 @@ const DEFAULT_RENDER_CELL = function(h, { row, column }) {
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const parseWidth = (width) => {
|
||||||
|
if (width !== undefined) {
|
||||||
|
width = parseInt(width, 10);
|
||||||
|
if (isNaN(width)) {
|
||||||
|
width = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return width;
|
||||||
|
};
|
||||||
|
|
||||||
|
const parseMinWidth = (minWidth) => {
|
||||||
|
if (minWidth !== undefined) {
|
||||||
|
minWidth = parseInt(minWidth, 10);
|
||||||
|
if (isNaN(minWidth)) {
|
||||||
|
minWidth = 80;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return minWidth;
|
||||||
|
};
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ElTableColumn',
|
name: 'ElTableColumn',
|
||||||
|
|
||||||
|
@ -205,25 +225,12 @@ export default {
|
||||||
let parent = this.columnOrTableParent;
|
let parent = this.columnOrTableParent;
|
||||||
let owner = this.owner;
|
let owner = this.owner;
|
||||||
this.isSubColumn = owner !== parent;
|
this.isSubColumn = owner !== parent;
|
||||||
this.columnId = (parent.tableId || (parent.columnId + '_')) + 'column_' + columnIdSeed++;
|
this.columnId = (parent.tableId || parent.columnId) + '_column_' + columnIdSeed++;
|
||||||
|
|
||||||
let type = this.type;
|
let type = this.type;
|
||||||
|
|
||||||
let width = this.width;
|
const width = parseWidth(this.width);
|
||||||
if (width !== undefined) {
|
const minWidth = parseMinWidth(this.minWidth);
|
||||||
width = parseInt(width, 10);
|
|
||||||
if (isNaN(width)) {
|
|
||||||
width = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let minWidth = this.minWidth;
|
|
||||||
if (minWidth !== undefined) {
|
|
||||||
minWidth = parseInt(minWidth, 10);
|
|
||||||
if (isNaN(minWidth)) {
|
|
||||||
minWidth = 80;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
let isColumnGroup = false;
|
let isColumnGroup = false;
|
||||||
|
|
||||||
|
@ -353,14 +360,14 @@ export default {
|
||||||
|
|
||||||
width(newVal) {
|
width(newVal) {
|
||||||
if (this.columnConfig) {
|
if (this.columnConfig) {
|
||||||
this.columnConfig.width = newVal;
|
this.columnConfig.width = parseWidth(newVal);
|
||||||
this.owner.store.scheduleLayout();
|
this.owner.store.scheduleLayout();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
minWidth(newVal) {
|
minWidth(newVal) {
|
||||||
if (this.columnConfig) {
|
if (this.columnConfig) {
|
||||||
this.columnConfig.minWidth = newVal;
|
this.columnConfig.minWidth = parseMinWidth(newVal);
|
||||||
this.owner.store.scheduleLayout();
|
this.owner.store.scheduleLayout();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
@ -368,7 +375,7 @@ export default {
|
||||||
fixed(newVal) {
|
fixed(newVal) {
|
||||||
if (this.columnConfig) {
|
if (this.columnConfig) {
|
||||||
this.columnConfig.fixed = newVal;
|
this.columnConfig.fixed = newVal;
|
||||||
this.owner.store.scheduleLayout();
|
this.owner.store.scheduleLayout(true);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,10 @@
|
||||||
|
import LayoutObserver from './layout-observer';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
name: 'ElTableFooter',
|
name: 'ElTableFooter',
|
||||||
|
|
||||||
|
mixins: [LayoutObserver],
|
||||||
|
|
||||||
render(h) {
|
render(h) {
|
||||||
const sums = [];
|
const sums = [];
|
||||||
this.columns.forEach((column, index) => {
|
this.columns.forEach((column, index) => {
|
||||||
|
@ -41,16 +45,10 @@ export default {
|
||||||
border="0">
|
border="0">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
{
|
{
|
||||||
this._l(this.columns, column =>
|
this._l(this.columns, column => <col name={ column.id } />)
|
||||||
<col
|
|
||||||
name={ column.id }
|
|
||||||
width={ column.realWidth || column.width }
|
|
||||||
/>)
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
!this.fixed && this.layout.gutterWidth
|
this.hasGutter ? <col name="gutter" /> : ''
|
||||||
? <col name="gutter" width={ this.layout.scrollY ? this.layout.gutterWidth : '' }></col>
|
|
||||||
: ''
|
|
||||||
}
|
}
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<tbody class={ [{ 'has-gutter': this.hasGutter }] }>
|
<tbody class={ [{ 'has-gutter': this.hasGutter }] }>
|
||||||
|
@ -70,9 +68,7 @@ export default {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this.hasGutter
|
this.hasGutter ? <th class="gutter"></th> : ''
|
||||||
? <td class="gutter" style={{ width: this.layout.scrollY ? this.layout.gutterWidth + 'px' : '0' }}></td>
|
|
||||||
: ''
|
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
|
@ -85,9 +81,6 @@ export default {
|
||||||
store: {
|
store: {
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
layout: {
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
summaryMethod: Function,
|
summaryMethod: Function,
|
||||||
sumText: String,
|
sumText: String,
|
||||||
border: Boolean,
|
border: Boolean,
|
||||||
|
@ -103,6 +96,10 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
table() {
|
||||||
|
return this.$parent;
|
||||||
|
},
|
||||||
|
|
||||||
isAllSelected() {
|
isAllSelected() {
|
||||||
return this.store.states.isAllSelected;
|
return this.store.states.isAllSelected;
|
||||||
},
|
},
|
||||||
|
@ -124,7 +121,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
hasGutter() {
|
hasGutter() {
|
||||||
return !this.fixed && this.layout.gutterWidth;
|
return !this.fixed && this.tableLayout.gutterWidth;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ import ElCheckbox from 'element-ui/packages/checkbox';
|
||||||
import ElTag from 'element-ui/packages/tag';
|
import ElTag from 'element-ui/packages/tag';
|
||||||
import Vue from 'vue';
|
import Vue from 'vue';
|
||||||
import FilterPanel from './filter-panel.vue';
|
import FilterPanel from './filter-panel.vue';
|
||||||
|
import LayoutObserver from './layout-observer';
|
||||||
|
|
||||||
const getAllColumns = (columns) => {
|
const getAllColumns = (columns) => {
|
||||||
const result = [];
|
const result = [];
|
||||||
|
@ -65,13 +66,14 @@ const convertToRows = (originColumns) => {
|
||||||
export default {
|
export default {
|
||||||
name: 'ElTableHeader',
|
name: 'ElTableHeader',
|
||||||
|
|
||||||
|
mixins: [LayoutObserver],
|
||||||
|
|
||||||
render(h) {
|
render(h) {
|
||||||
const originColumns = this.store.states.originColumns;
|
const originColumns = this.store.states.originColumns;
|
||||||
const columnRows = convertToRows(originColumns, this.columns);
|
const columnRows = convertToRows(originColumns, this.columns);
|
||||||
// 是否拥有多级表头
|
// 是否拥有多级表头
|
||||||
const isGroup = columnRows.length > 1;
|
const isGroup = columnRows.length > 1;
|
||||||
if (isGroup) this.$parent.isGroup = true;
|
if (isGroup) this.$parent.isGroup = true;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<table
|
<table
|
||||||
class="el-table__header"
|
class="el-table__header"
|
||||||
|
@ -80,16 +82,10 @@ export default {
|
||||||
border="0">
|
border="0">
|
||||||
<colgroup>
|
<colgroup>
|
||||||
{
|
{
|
||||||
this._l(this.columns, column =>
|
this._l(this.columns, column => <col name={ column.id } />)
|
||||||
<col
|
|
||||||
name={ column.id }
|
|
||||||
width={ column.realWidth || column.width }
|
|
||||||
/>)
|
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
!this.fixed && this.layout.gutterWidth
|
this.hasGutter ? <col name="gutter" /> : ''
|
||||||
? <col name="gutter" width={ this.layout.scrollY ? this.layout.gutterWidth : '' }></col>
|
|
||||||
: ''
|
|
||||||
}
|
}
|
||||||
</colgroup>
|
</colgroup>
|
||||||
<thead class={ [{ 'is-group': isGroup, 'has-gutter': this.hasGutter }] }>
|
<thead class={ [{ 'is-group': isGroup, 'has-gutter': this.hasGutter }] }>
|
||||||
|
@ -137,12 +133,7 @@ export default {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
this.hasGutter
|
this.hasGutter ? <th class="gutter"></th> : ''
|
||||||
? <th class="gutter" style={{
|
|
||||||
width: this.layout.scrollY ? this.layout.gutterWidth + 'px' : '0',
|
|
||||||
display: this.layout.scrollY ? '' : 'none'
|
|
||||||
}}></th>
|
|
||||||
: ''
|
|
||||||
}
|
}
|
||||||
</tr>
|
</tr>
|
||||||
)
|
)
|
||||||
|
@ -157,9 +148,6 @@ export default {
|
||||||
store: {
|
store: {
|
||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
layout: {
|
|
||||||
required: true
|
|
||||||
},
|
|
||||||
border: Boolean,
|
border: Boolean,
|
||||||
defaultSort: {
|
defaultSort: {
|
||||||
type: Object,
|
type: Object,
|
||||||
|
@ -211,7 +199,7 @@ export default {
|
||||||
},
|
},
|
||||||
|
|
||||||
hasGutter() {
|
hasGutter() {
|
||||||
return !this.fixed && this.layout.gutterWidth;
|
return !this.fixed && this.tableLayout.gutterWidth;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
import scrollbarWidth from 'element-ui/src/utils/scrollbar-width';
|
import scrollbarWidth from 'element-ui/src/utils/scrollbar-width';
|
||||||
|
import Vue from 'vue';
|
||||||
|
|
||||||
class TableLayout {
|
class TableLayout {
|
||||||
constructor(options) {
|
constructor(options) {
|
||||||
|
this.observers = [];
|
||||||
this.table = null;
|
this.table = null;
|
||||||
this.store = null;
|
this.store = null;
|
||||||
this.columns = null;
|
this.columns = null;
|
||||||
|
@ -43,7 +45,7 @@ class TableLayout {
|
||||||
const bodyWrapper = this.table.bodyWrapper;
|
const bodyWrapper = this.table.bodyWrapper;
|
||||||
if (this.table.$el && bodyWrapper) {
|
if (this.table.$el && bodyWrapper) {
|
||||||
const body = bodyWrapper.querySelector('.el-table__body');
|
const body = bodyWrapper.querySelector('.el-table__body');
|
||||||
this.scrollY = body.offsetHeight > bodyWrapper.offsetHeight;
|
this.scrollY = body.offsetHeight > this.bodyHeight;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,19 +54,19 @@ class TableLayout {
|
||||||
if (typeof value === 'string' && /^\d+$/.test(value)) {
|
if (typeof value === 'string' && /^\d+$/.test(value)) {
|
||||||
value = Number(value);
|
value = Number(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.height = value;
|
this.height = value;
|
||||||
|
|
||||||
if (!el) return;
|
if (!el && value) return Vue.nextTick(() => this.setHeight(value, prop));
|
||||||
|
|
||||||
if (typeof value === 'number') {
|
if (typeof value === 'number') {
|
||||||
el.style[prop] = value + 'px';
|
el.style[prop] = value + 'px';
|
||||||
|
|
||||||
this.updateHeight();
|
this.updateElsHeight();
|
||||||
} else if (typeof value === 'string') {
|
} else if (typeof value === 'string') {
|
||||||
if (value === '') {
|
if (value === '') {
|
||||||
el.style[prop] = '';
|
el.style[prop] = '';
|
||||||
}
|
}
|
||||||
this.updateHeight();
|
this.updateElsHeight();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,37 +74,33 @@ class TableLayout {
|
||||||
return this.setHeight(value, 'max-height');
|
return this.setHeight(value, 'max-height');
|
||||||
}
|
}
|
||||||
|
|
||||||
updateHeight() {
|
updateElsHeight() {
|
||||||
const height = this.tableHeight = this.table.$el.clientHeight;
|
if (!this.table.$ready) return Vue.nextTick(() => this.updateElsHeight());
|
||||||
const noData = !this.table.data || this.table.data.length === 0;
|
|
||||||
const { headerWrapper, appendWrapper, footerWrapper } = this.table.$refs;
|
const { headerWrapper, appendWrapper, footerWrapper } = this.table.$refs;
|
||||||
const footerHeight = this.footerHeight = footerWrapper ? footerWrapper.offsetHeight : 0;
|
|
||||||
this.appendHeight = appendWrapper ? appendWrapper.offsetHeight : 0;
|
this.appendHeight = appendWrapper ? appendWrapper.offsetHeight : 0;
|
||||||
|
|
||||||
if (this.showHeader && !headerWrapper) return;
|
if (this.showHeader && !headerWrapper) return;
|
||||||
if (!this.showHeader) {
|
const headerHeight = this.headerHeight = !this.showHeader ? 0 : headerWrapper.offsetHeight;
|
||||||
this.headerHeight = 0;
|
if (this.showHeader && headerWrapper.offsetWidth > 0 && headerHeight < 2) {
|
||||||
if (this.height !== null && (!isNaN(this.height) || typeof this.height === 'string')) {
|
return Vue.nextTick(() => this.updateElsHeight());
|
||||||
this.bodyHeight = height - footerHeight + (footerWrapper ? 1 : 0);
|
|
||||||
}
|
|
||||||
this.fixedBodyHeight = this.scrollX ? height - this.gutterWidth : height;
|
|
||||||
} else {
|
|
||||||
const headerHeight = this.headerHeight = headerWrapper.offsetHeight;
|
|
||||||
const bodyHeight = height - headerHeight - footerHeight + (footerWrapper ? 1 : 0);
|
|
||||||
if (this.height !== null && (!isNaN(this.height) || typeof this.height === 'string')) {
|
|
||||||
this.bodyHeight = bodyHeight;
|
|
||||||
}
|
|
||||||
this.fixedBodyHeight = this.scrollX ? bodyHeight - this.gutterWidth : bodyHeight;
|
|
||||||
}
|
}
|
||||||
this.viewportHeight = this.scrollX ? height - (noData ? 0 : this.gutterWidth) : height;
|
const tableHeight = this.tableHeight = this.table.$el.clientHeight;
|
||||||
|
if (this.height !== null && (!isNaN(this.height) || typeof this.height === 'string')) {
|
||||||
|
const footerHeight = this.footerHeight = footerWrapper ? footerWrapper.offsetHeight : 0;
|
||||||
|
this.bodyHeight = tableHeight - headerHeight - footerHeight + (footerWrapper ? 1 : 0);
|
||||||
|
}
|
||||||
|
this.fixedBodyHeight = this.scrollX ? this.bodyHeight - this.gutterWidth : this.bodyHeight;
|
||||||
|
|
||||||
|
const noData = !this.table.data || this.table.data.length === 0;
|
||||||
|
this.viewportHeight = this.scrollX ? tableHeight - (noData ? 0 : this.gutterWidth) : tableHeight;
|
||||||
|
|
||||||
|
this.updateScrollY();
|
||||||
|
this.notifyObservers('scrollable');
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
getFlattenColumns() {
|
||||||
const fit = this.fit;
|
|
||||||
const columns = this.table.columns;
|
|
||||||
const bodyWidth = this.table.$el.clientWidth;
|
|
||||||
let bodyMinWidth = 0;
|
|
||||||
|
|
||||||
const flattenColumns = [];
|
const flattenColumns = [];
|
||||||
|
const columns = this.table.columns;
|
||||||
columns.forEach((column) => {
|
columns.forEach((column) => {
|
||||||
if (column.isColumnGroup) {
|
if (column.isColumnGroup) {
|
||||||
flattenColumns.push.apply(flattenColumns, column.columns);
|
flattenColumns.push.apply(flattenColumns, column.columns);
|
||||||
|
@ -111,8 +109,21 @@ class TableLayout {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return flattenColumns;
|
||||||
|
}
|
||||||
|
|
||||||
|
updateColumnsWidth() {
|
||||||
|
const fit = this.fit;
|
||||||
|
const bodyWidth = this.table.$el.clientWidth;
|
||||||
|
let bodyMinWidth = 0;
|
||||||
|
|
||||||
|
const flattenColumns = this.getFlattenColumns();
|
||||||
let flexColumns = flattenColumns.filter((column) => typeof column.width !== 'number');
|
let flexColumns = flattenColumns.filter((column) => typeof column.width !== 'number');
|
||||||
|
|
||||||
|
flattenColumns.forEach((column) => { // Clean those columns whose width changed from flex to unflex
|
||||||
|
if (typeof column.width === 'number' && column.realWidth) column.realWidth = null;
|
||||||
|
});
|
||||||
|
|
||||||
if (flexColumns.length > 0 && fit) {
|
if (flexColumns.length > 0 && fit) {
|
||||||
flattenColumns.forEach((column) => {
|
flattenColumns.forEach((column) => {
|
||||||
bodyMinWidth += column.width || column.minWidth || 80;
|
bodyMinWidth += column.width || column.minWidth || 80;
|
||||||
|
@ -169,7 +180,7 @@ class TableLayout {
|
||||||
if (fixedColumns.length > 0) {
|
if (fixedColumns.length > 0) {
|
||||||
let fixedWidth = 0;
|
let fixedWidth = 0;
|
||||||
fixedColumns.forEach(function(column) {
|
fixedColumns.forEach(function(column) {
|
||||||
fixedWidth += column.realWidth;
|
fixedWidth += column.realWidth || column.width;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.fixedWidth = fixedWidth;
|
this.fixedWidth = fixedWidth;
|
||||||
|
@ -179,11 +190,40 @@ class TableLayout {
|
||||||
if (rightFixedColumns.length > 0) {
|
if (rightFixedColumns.length > 0) {
|
||||||
let rightFixedWidth = 0;
|
let rightFixedWidth = 0;
|
||||||
rightFixedColumns.forEach(function(column) {
|
rightFixedColumns.forEach(function(column) {
|
||||||
rightFixedWidth += column.realWidth;
|
rightFixedWidth += column.realWidth || column.width;
|
||||||
});
|
});
|
||||||
|
|
||||||
this.rightFixedWidth = rightFixedWidth;
|
this.rightFixedWidth = rightFixedWidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.notifyObservers('columns');
|
||||||
|
}
|
||||||
|
|
||||||
|
addObserver(observer) {
|
||||||
|
this.observers.push(observer);
|
||||||
|
}
|
||||||
|
|
||||||
|
removeObserver(observer) {
|
||||||
|
const index = this.observers.indexOf(observer);
|
||||||
|
if (index !== -1) {
|
||||||
|
this.observers.splice(index, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
notifyObservers(event) {
|
||||||
|
const observers = this.observers;
|
||||||
|
observers.forEach((observer) => {
|
||||||
|
switch (event) {
|
||||||
|
case 'columns':
|
||||||
|
observer.onColumnsChange(this);
|
||||||
|
break;
|
||||||
|
case 'scrollable':
|
||||||
|
observer.onScrollableChange(this);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`Table Layout don't have event ${event}.`);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,6 @@ const TableStore = function(table, initialState = {}) {
|
||||||
fixedLeafColumnsLength: 0,
|
fixedLeafColumnsLength: 0,
|
||||||
rightFixedLeafColumnsLength: 0,
|
rightFixedLeafColumnsLength: 0,
|
||||||
isComplex: false,
|
isComplex: false,
|
||||||
_data: null,
|
|
||||||
filteredData: null,
|
filteredData: null,
|
||||||
data: null,
|
data: null,
|
||||||
sortingColumn: null,
|
sortingColumn: null,
|
||||||
|
@ -137,15 +136,6 @@ TableStore.prototype.mutations = {
|
||||||
states.filteredData = data;
|
states.filteredData = data;
|
||||||
states.data = sortData((data || []), states);
|
states.data = sortData((data || []), states);
|
||||||
|
|
||||||
// states.data.forEach((item) => {
|
|
||||||
// if (!item.$extra) {
|
|
||||||
// Object.defineProperty(item, '$extra', {
|
|
||||||
// value: {},
|
|
||||||
// enumerable: false
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
|
|
||||||
this.updateCurrentRow();
|
this.updateCurrentRow();
|
||||||
|
|
||||||
if (!states.reserveSelection) {
|
if (!states.reserveSelection) {
|
||||||
|
@ -252,8 +242,10 @@ TableStore.prototype.mutations = {
|
||||||
states.reserveSelection = column.reserveSelection;
|
states.reserveSelection = column.reserveSelection;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateColumns(); // hack for dynamics insert column
|
if (this.table.$ready) {
|
||||||
this.scheduleLayout();
|
this.updateColumns(); // hack for dynamics insert column
|
||||||
|
this.scheduleLayout();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
removeColumn(states, column, parent) {
|
removeColumn(states, column, parent) {
|
||||||
|
@ -266,8 +258,10 @@ TableStore.prototype.mutations = {
|
||||||
array.splice(array.indexOf(column), 1);
|
array.splice(array.indexOf(column), 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.updateColumns(); // hack for dynamics remove column
|
if (this.table.$ready) {
|
||||||
this.scheduleLayout();
|
this.updateColumns(); // hack for dynamics remove column
|
||||||
|
this.scheduleLayout();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
setHoverRow(states, row) {
|
setHoverRow(states, row) {
|
||||||
|
@ -370,7 +364,9 @@ TableStore.prototype.clearSelection = function() {
|
||||||
const states = this.states;
|
const states = this.states;
|
||||||
states.isAllSelected = false;
|
states.isAllSelected = false;
|
||||||
const oldSelection = states.selection;
|
const oldSelection = states.selection;
|
||||||
states.selection = [];
|
if (states.selection.length) {
|
||||||
|
states.selection = [];
|
||||||
|
}
|
||||||
if (oldSelection.length > 0) {
|
if (oldSelection.length > 0) {
|
||||||
this.table.$emit('selection-change', states.selection ? states.selection.slice() : []);
|
this.table.$emit('selection-change', states.selection ? states.selection.slice() : []);
|
||||||
}
|
}
|
||||||
|
@ -531,8 +527,11 @@ TableStore.prototype.updateAllSelected = function() {
|
||||||
states.isAllSelected = isAllSelected;
|
states.isAllSelected = isAllSelected;
|
||||||
};
|
};
|
||||||
|
|
||||||
TableStore.prototype.scheduleLayout = function() {
|
TableStore.prototype.scheduleLayout = function(updateColumns) {
|
||||||
this.table.debouncedLayout();
|
if (updateColumns) {
|
||||||
|
this.updateColumns();
|
||||||
|
}
|
||||||
|
this.table.debouncedUpdateLayout();
|
||||||
};
|
};
|
||||||
|
|
||||||
TableStore.prototype.setCurrentRowKey = function(key) {
|
TableStore.prototype.setCurrentRowKey = function(key) {
|
||||||
|
|
|
@ -7,154 +7,213 @@
|
||||||
'el-table--hidden': isHidden,
|
'el-table--hidden': isHidden,
|
||||||
'el-table--group': isGroup,
|
'el-table--group': isGroup,
|
||||||
'el-table--fluid-height': maxHeight,
|
'el-table--fluid-height': maxHeight,
|
||||||
|
'el-table--scrollable-x': layout.scrollX,
|
||||||
|
'el-table--scrollable-y': layout.scrollY,
|
||||||
'el-table--enable-row-hover': !store.states.isComplex,
|
'el-table--enable-row-hover': !store.states.isComplex,
|
||||||
'el-table--enable-row-transition': (store.states.data || []).length !== 0 && (store.states.data || []).length < 100
|
'el-table--enable-row-transition': (store.states.data || []).length !== 0 && (store.states.data || []).length < 100
|
||||||
}, tableSize ? `el-table--${ tableSize }` : '']"
|
}, tableSize ? `el-table--${ tableSize }` : '']"
|
||||||
@mouseleave="handleMouseLeave($event)">
|
@mouseleave="handleMouseLeave($event)">
|
||||||
<div class="hidden-columns" ref="hiddenColumns"><slot></slot></div>
|
<div class="hidden-columns" ref="hiddenColumns"><slot></slot></div>
|
||||||
<div class="el-table__header-wrapper" ref="headerWrapper" v-if="showHeader" v-mousewheel="handleHeaderFooterMousewheel">
|
<div
|
||||||
|
v-if="showHeader"
|
||||||
|
v-mousewheel="handleHeaderFooterMousewheel"
|
||||||
|
class="el-table__header-wrapper"
|
||||||
|
ref="headerWrapper">
|
||||||
<table-header
|
<table-header
|
||||||
ref="tableHeader"
|
ref="tableHeader"
|
||||||
:store="store"
|
:store="store"
|
||||||
:layout="layout"
|
|
||||||
:border="border"
|
:border="border"
|
||||||
:default-sort="defaultSort"
|
:default-sort="defaultSort"
|
||||||
:style="{ width: layout.bodyWidth ? layout.bodyWidth + 'px' : '' }">
|
:style="{
|
||||||
|
width: layout.bodyWidth ? layout.bodyWidth + 'px' : ''
|
||||||
|
}">
|
||||||
</table-header>
|
</table-header>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="el-table__body-wrapper"
|
class="el-table__body-wrapper"
|
||||||
ref="bodyWrapper"
|
ref="bodyWrapper"
|
||||||
:class="[layout.scrollX ? `is-scroll-${scrollPosition}` : 'is-scroll-none']"
|
:class="[layout.scrollX ? `is-scrolling-${scrollPosition}` : 'is-scrolling-none']"
|
||||||
:style="[bodyHeight]">
|
:style="[bodyHeight]">
|
||||||
<table-body
|
<table-body
|
||||||
:context="context"
|
:context="context"
|
||||||
:store="store"
|
:store="store"
|
||||||
:stripe="stripe"
|
:stripe="stripe"
|
||||||
:layout="layout"
|
|
||||||
:row-class-name="rowClassName"
|
:row-class-name="rowClassName"
|
||||||
:row-style="rowStyle"
|
:row-style="rowStyle"
|
||||||
:highlight="highlightCurrentRow"
|
:highlight="highlightCurrentRow"
|
||||||
:style="{ width: bodyWidth }">
|
:style="{
|
||||||
|
width: bodyWidth
|
||||||
|
}">
|
||||||
</table-body>
|
</table-body>
|
||||||
<div :style="{ width: bodyWidth }" class="el-table__empty-block" v-if="!data || data.length === 0">
|
<div
|
||||||
<span class="el-table__empty-text"><slot name="empty">{{ emptyText || t('el.table.emptyText') }}</slot></span>
|
v-if="!data || data.length === 0"
|
||||||
|
class="el-table__empty-block"
|
||||||
|
ref="emptyBlock"
|
||||||
|
:style="{
|
||||||
|
width: bodyWidth
|
||||||
|
}">
|
||||||
|
<span class="el-table__empty-text">
|
||||||
|
<slot name="empty">{{ emptyText || t('el.table.emptyText') }}</slot>
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div class="el-table__append-wrapper" ref="appendWrapper" v-if="$slots.append">
|
<div
|
||||||
|
v-if="$slots.append"
|
||||||
|
class="el-table__append-wrapper"
|
||||||
|
ref="appendWrapper">
|
||||||
<slot name="append"></slot>
|
<slot name="append"></slot>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="el-table__footer-wrapper" ref="footerWrapper" v-if="showSummary" v-show="data && data.length > 0" v-mousewheel="handleHeaderFooterMousewheel">
|
<div
|
||||||
|
v-if="showSummary"
|
||||||
|
v-show="data && data.length > 0"
|
||||||
|
v-mousewheel="handleHeaderFooterMousewheel"
|
||||||
|
class="el-table__footer-wrapper"
|
||||||
|
ref="footerWrapper">
|
||||||
<table-footer
|
<table-footer
|
||||||
:store="store"
|
:store="store"
|
||||||
:layout="layout"
|
|
||||||
:border="border"
|
:border="border"
|
||||||
:sum-text="sumText || t('el.table.sumText')"
|
:sum-text="sumText || t('el.table.sumText')"
|
||||||
:summary-method="summaryMethod"
|
:summary-method="summaryMethod"
|
||||||
:default-sort="defaultSort"
|
:default-sort="defaultSort"
|
||||||
:style="{ width: layout.bodyWidth ? layout.bodyWidth + 'px' : '' }">
|
:style="{
|
||||||
|
width: layout.bodyWidth ? layout.bodyWidth + 'px' : ''
|
||||||
|
}">
|
||||||
</table-footer>
|
</table-footer>
|
||||||
</div>
|
</div>
|
||||||
<div class="el-table__fixed" ref="fixedWrapper"
|
<div
|
||||||
v-if="fixedColumns.length > 0"
|
v-if="fixedColumns.length > 0"
|
||||||
v-mousewheel="handleFixedMousewheel"
|
v-mousewheel="handleFixedMousewheel"
|
||||||
:style="[
|
class="el-table__fixed"
|
||||||
{ width: layout.fixedWidth ? layout.fixedWidth + 'px' : '' },
|
ref="fixedWrapper"
|
||||||
fixedHeight
|
:style="[{
|
||||||
]">
|
width: layout.fixedWidth ? layout.fixedWidth + 'px' : ''
|
||||||
<div class="el-table__fixed-header-wrapper" ref="fixedHeaderWrapper" v-if="showHeader">
|
},
|
||||||
|
fixedHeight]">
|
||||||
|
<div
|
||||||
|
v-if="showHeader"
|
||||||
|
class="el-table__fixed-header-wrapper"
|
||||||
|
ref="fixedHeaderWrapper" >
|
||||||
<table-header
|
<table-header
|
||||||
ref="fixedTableHeader"
|
ref="fixedTableHeader"
|
||||||
fixed="left"
|
fixed="left"
|
||||||
:border="border"
|
:border="border"
|
||||||
:store="store"
|
:store="store"
|
||||||
:layout="layout"
|
:style="{
|
||||||
:style="{ width: layout.fixedWidth ? layout.fixedWidth + 'px' : '' }"></table-header>
|
width: layout.fixedWidth ? layout.fixedWidth + 'px' : ''
|
||||||
|
}"></table-header>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="el-table__fixed-body-wrapper"
|
class="el-table__fixed-body-wrapper"
|
||||||
ref="fixedBodyWrapper"
|
ref="fixedBodyWrapper"
|
||||||
:style="[
|
:style="[{
|
||||||
{ top: layout.headerHeight + 'px' },
|
top: layout.headerHeight + 'px'
|
||||||
fixedBodyHeight
|
},
|
||||||
]">
|
fixedBodyHeight]">
|
||||||
<table-body
|
<table-body
|
||||||
fixed="left"
|
fixed="left"
|
||||||
:store="store"
|
:store="store"
|
||||||
:stripe="stripe"
|
:stripe="stripe"
|
||||||
:layout="layout"
|
|
||||||
:highlight="highlightCurrentRow"
|
:highlight="highlightCurrentRow"
|
||||||
:row-class-name="rowClassName"
|
:row-class-name="rowClassName"
|
||||||
:row-style="rowStyle"
|
:row-style="rowStyle"
|
||||||
:style="{ width: layout.fixedWidth ? layout.fixedWidth + 'px' : '' }">
|
:style="{
|
||||||
|
width: layout.fixedWidth ? layout.fixedWidth + 'px' : ''
|
||||||
|
}">
|
||||||
</table-body>
|
</table-body>
|
||||||
<div class="el-table__append-gutter" :style="{ height: layout.appendHeight + 'px' }" v-if="$slots.append"></div>
|
<div
|
||||||
|
v-if="$slots.append"
|
||||||
|
class="el-table__append-gutter"
|
||||||
|
:style="{
|
||||||
|
height: layout.appendHeight + 'px'
|
||||||
|
}"></div>
|
||||||
</div>
|
</div>
|
||||||
<div class="el-table__fixed-footer-wrapper" ref="fixedFooterWrapper" v-if="showSummary" v-show="data && data.length > 0">
|
<div
|
||||||
|
v-if="showSummary"
|
||||||
|
v-show="data && data.length > 0"
|
||||||
|
class="el-table__fixed-footer-wrapper"
|
||||||
|
ref="fixedFooterWrapper">
|
||||||
<table-footer
|
<table-footer
|
||||||
fixed="left"
|
fixed="left"
|
||||||
:border="border"
|
:border="border"
|
||||||
:sum-text="sumText || t('el.table.sumText')"
|
:sum-text="sumText || t('el.table.sumText')"
|
||||||
:summary-method="summaryMethod"
|
:summary-method="summaryMethod"
|
||||||
:store="store"
|
:store="store"
|
||||||
:layout="layout"
|
:style="{
|
||||||
:style="{ width: layout.fixedWidth ? layout.fixedWidth + 'px' : '' }"></table-footer>
|
width: layout.fixedWidth ? layout.fixedWidth + 'px' : ''
|
||||||
|
}"></table-footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="el-table__fixed-right" ref="rightFixedWrapper"
|
<div
|
||||||
v-if="rightFixedColumns.length > 0"
|
v-if="rightFixedColumns.length > 0"
|
||||||
v-mousewheel="handleFixedMousewheel"
|
v-mousewheel="handleFixedMousewheel"
|
||||||
:style="[
|
class="el-table__fixed-right"
|
||||||
{ width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : '' },
|
ref="rightFixedWrapper"
|
||||||
{ right: layout.scrollY ? (border ? layout.gutterWidth : (layout.gutterWidth || 0)) + 'px' : '' },
|
:style="[{
|
||||||
fixedHeight
|
width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : '',
|
||||||
]">
|
right: layout.scrollY ? (border ? layout.gutterWidth : (layout.gutterWidth || 0)) + 'px' : ''
|
||||||
<div class="el-table__fixed-header-wrapper" ref="rightFixedHeaderWrapper" v-if="showHeader">
|
},
|
||||||
|
fixedHeight]">
|
||||||
|
<div v-if="showHeader"
|
||||||
|
class="el-table__fixed-header-wrapper"
|
||||||
|
ref="rightFixedHeaderWrapper">
|
||||||
<table-header
|
<table-header
|
||||||
ref="rightFixedTableHeader"
|
ref="rightFixedTableHeader"
|
||||||
fixed="right"
|
fixed="right"
|
||||||
:border="border"
|
:border="border"
|
||||||
:store="store"
|
:store="store"
|
||||||
:layout="layout"
|
:style="{
|
||||||
:style="{ width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : '' }"></table-header>
|
width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : ''
|
||||||
|
}"></table-header>
|
||||||
</div>
|
</div>
|
||||||
<div class="el-table__fixed-body-wrapper" ref="rightFixedBodyWrapper"
|
<div
|
||||||
:style="[
|
class="el-table__fixed-body-wrapper"
|
||||||
{ top: layout.headerHeight + 'px' },
|
ref="rightFixedBodyWrapper"
|
||||||
fixedBodyHeight
|
:style="[{
|
||||||
]">
|
top: layout.headerHeight + 'px'
|
||||||
|
},
|
||||||
|
fixedBodyHeight]">
|
||||||
<table-body
|
<table-body
|
||||||
fixed="right"
|
fixed="right"
|
||||||
:store="store"
|
:store="store"
|
||||||
:stripe="stripe"
|
:stripe="stripe"
|
||||||
:layout="layout"
|
|
||||||
:row-class-name="rowClassName"
|
:row-class-name="rowClassName"
|
||||||
:row-style="rowStyle"
|
:row-style="rowStyle"
|
||||||
:highlight="highlightCurrentRow"
|
:highlight="highlightCurrentRow"
|
||||||
:style="{ width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : '' }">
|
:style="{
|
||||||
|
width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : ''
|
||||||
|
}">
|
||||||
</table-body>
|
</table-body>
|
||||||
</div>
|
</div>
|
||||||
<div class="el-table__fixed-footer-wrapper" ref="rightFixedFooterWrapper" v-if="showSummary" v-show="data && data.length > 0">
|
<div
|
||||||
|
v-if="showSummary"
|
||||||
|
v-show="data && data.length > 0"
|
||||||
|
class="el-table__fixed-footer-wrapper"
|
||||||
|
ref="rightFixedFooterWrapper">
|
||||||
<table-footer
|
<table-footer
|
||||||
fixed="right"
|
fixed="right"
|
||||||
:border="border"
|
:border="border"
|
||||||
:sum-text="sumText || t('el.table.sumText')"
|
:sum-text="sumText || t('el.table.sumText')"
|
||||||
:summary-method="summaryMethod"
|
:summary-method="summaryMethod"
|
||||||
:store="store"
|
:store="store"
|
||||||
:layout="layout"
|
:style="{
|
||||||
:style="{ width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : '' }"></table-footer>
|
width: layout.rightFixedWidth ? layout.rightFixedWidth + 'px' : ''
|
||||||
|
}"></table-footer>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="el-table__fixed-right-patch"
|
<div
|
||||||
v-if="rightFixedColumns.length > 0"
|
v-if="rightFixedColumns.length > 0"
|
||||||
:style="{ width: layout.scrollY ? layout.gutterWidth + 'px' : '0', height: layout.headerHeight + 'px' }"></div>
|
class="el-table__fixed-right-patch"
|
||||||
|
ref="rightFixedPatch"
|
||||||
|
:style="{
|
||||||
|
width: layout.scrollY ? layout.gutterWidth + 'px' : '0',
|
||||||
|
height: layout.headerHeight + 'px'
|
||||||
|
}"></div>
|
||||||
<div class="el-table__column-resize-proxy" ref="resizeProxy" v-show="resizeProxyVisible"></div>
|
<div class="el-table__column-resize-proxy" ref="resizeProxy" v-show="resizeProxyVisible"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script type="text/babel">
|
<script type="text/babel">
|
||||||
import ElCheckbox from 'element-ui/packages/checkbox';
|
import ElCheckbox from 'element-ui/packages/checkbox';
|
||||||
import throttle from 'throttle-debounce/throttle';
|
|
||||||
import debounce from 'throttle-debounce/debounce';
|
import debounce from 'throttle-debounce/debounce';
|
||||||
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
|
import { addResizeListener, removeResizeListener } from 'element-ui/src/utils/resize-event';
|
||||||
import Mousewheel from 'element-ui/src/directives/mousewheel';
|
import Mousewheel from 'element-ui/src/directives/mousewheel';
|
||||||
|
@ -346,32 +405,44 @@
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.fit) {
|
if (this.fit) {
|
||||||
this.windowResizeListener = throttle(50, () => {
|
addResizeListener(this.$el, this.resizeListener);
|
||||||
if (this.$ready) this.doLayout();
|
}
|
||||||
});
|
},
|
||||||
addResizeListener(this.$el, this.windowResizeListener);
|
|
||||||
|
resizeListener() {
|
||||||
|
if (!this.$ready) return;
|
||||||
|
let shouldUpdateLayout = false;
|
||||||
|
const el = this.$el;
|
||||||
|
const { width: oldWidth, height: oldHeight } = this.resizeState;
|
||||||
|
|
||||||
|
const width = el.offsetWidth;
|
||||||
|
if (oldWidth !== width) {
|
||||||
|
shouldUpdateLayout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const height = el.offsetHeight;
|
||||||
|
if (this.height && oldHeight !== height) {
|
||||||
|
shouldUpdateLayout = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (shouldUpdateLayout) {
|
||||||
|
this.resizeState.width = width;
|
||||||
|
this.resizeState.height = height;
|
||||||
|
this.doLayout();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
doLayout() {
|
doLayout() {
|
||||||
this.store.updateColumns();
|
if (this.shouldUpdateHeight) {
|
||||||
this.updateScrollY();
|
this.layout.updateElsHeight();
|
||||||
this.layout.update();
|
}
|
||||||
this.$nextTick(() => {
|
this.layout.updateColumnsWidth();
|
||||||
if (this.height) {
|
|
||||||
this.layout.setHeight(this.height);
|
|
||||||
} else if (this.maxHeight) {
|
|
||||||
this.layout.setMaxHeight(this.maxHeight);
|
|
||||||
} else if (this.shouldUpdateHeight) {
|
|
||||||
this.layout.updateHeight();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
created() {
|
created() {
|
||||||
this.tableId = 'el-table_' + tableIdSeed + '_';
|
this.tableId = 'el-table_' + tableIdSeed++;
|
||||||
this.debouncedLayout = debounce(50, () => this.doLayout());
|
this.debouncedUpdateLayout = debounce(50, () => this.doLayout());
|
||||||
},
|
},
|
||||||
|
|
||||||
computed: {
|
computed: {
|
||||||
|
@ -384,7 +455,7 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
shouldUpdateHeight() {
|
shouldUpdateHeight() {
|
||||||
return typeof this.height === 'number' ||
|
return this.height ||
|
||||||
this.fixedColumns.length > 0 ||
|
this.fixedColumns.length > 0 ||
|
||||||
this.rightFixedColumns.length > 0;
|
this.rightFixedColumns.length > 0;
|
||||||
},
|
},
|
||||||
|
@ -409,34 +480,29 @@
|
||||||
return this.store.states.rightFixedColumns;
|
return this.store.states.rightFixedColumns;
|
||||||
},
|
},
|
||||||
|
|
||||||
bodyHeight() {
|
|
||||||
let style = {};
|
|
||||||
|
|
||||||
if (this.height) {
|
|
||||||
style = {
|
|
||||||
height: this.layout.bodyHeight ? this.layout.bodyHeight + 'px' : ''
|
|
||||||
};
|
|
||||||
} else if (this.maxHeight) {
|
|
||||||
style = {
|
|
||||||
'max-height': (this.showHeader
|
|
||||||
? this.maxHeight - this.layout.headerHeight - this.layout.footerHeight
|
|
||||||
: this.maxHeight - this.layout.footerHeight) + 'px'
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
return style;
|
|
||||||
},
|
|
||||||
|
|
||||||
bodyWidth() {
|
bodyWidth() {
|
||||||
const { bodyWidth, scrollY, gutterWidth } = this.layout;
|
const { bodyWidth, scrollY, gutterWidth } = this.layout;
|
||||||
return bodyWidth ? bodyWidth - (scrollY ? gutterWidth : 0) + 'px' : '';
|
return bodyWidth ? bodyWidth - (scrollY ? gutterWidth : 0) + 'px' : '';
|
||||||
},
|
},
|
||||||
|
|
||||||
fixedBodyHeight() {
|
bodyHeight() {
|
||||||
let style = {};
|
|
||||||
|
|
||||||
if (this.height) {
|
if (this.height) {
|
||||||
style = {
|
return {
|
||||||
|
height: this.layout.bodyHeight ? this.layout.bodyHeight + 'px' : ''
|
||||||
|
};
|
||||||
|
} else if (this.maxHeight) {
|
||||||
|
return {
|
||||||
|
'max-height': (this.showHeader
|
||||||
|
? this.maxHeight - this.layout.headerHeight - this.layout.footerHeight
|
||||||
|
: this.maxHeight - this.layout.footerHeight) + 'px'
|
||||||
|
};
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
|
||||||
|
fixedBodyHeight() {
|
||||||
|
if (this.height) {
|
||||||
|
return {
|
||||||
height: this.layout.fixedBodyHeight ? this.layout.fixedBodyHeight + 'px' : ''
|
height: this.layout.fixedBodyHeight ? this.layout.fixedBodyHeight + 'px' : ''
|
||||||
};
|
};
|
||||||
} else if (this.maxHeight) {
|
} else if (this.maxHeight) {
|
||||||
|
@ -448,38 +514,40 @@
|
||||||
|
|
||||||
maxHeight -= this.layout.footerHeight;
|
maxHeight -= this.layout.footerHeight;
|
||||||
|
|
||||||
style = {
|
return {
|
||||||
'max-height': maxHeight + 'px'
|
'max-height': maxHeight + 'px'
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return style;
|
return {};
|
||||||
},
|
},
|
||||||
|
|
||||||
fixedHeight() {
|
fixedHeight() {
|
||||||
let style = {};
|
|
||||||
|
|
||||||
if (this.maxHeight) {
|
if (this.maxHeight) {
|
||||||
style = {
|
return {
|
||||||
bottom: (this.layout.scrollX && this.data.length) ? this.layout.gutterWidth + 'px' : ''
|
bottom: (this.layout.scrollX && this.data.length) ? this.layout.gutterWidth + 'px' : ''
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
style = {
|
return {
|
||||||
height: this.layout.viewportHeight ? this.layout.viewportHeight + 'px' : ''
|
height: this.layout.viewportHeight ? this.layout.viewportHeight + 'px' : ''
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
return style;
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
watch: {
|
watch: {
|
||||||
height(value) {
|
height: {
|
||||||
this.layout.setHeight(value);
|
immediate: true,
|
||||||
|
handler(value) {
|
||||||
|
this.layout.setHeight(value);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
maxHeight(value) {
|
maxHeight: {
|
||||||
this.layout.setMaxHeight(value);
|
immediate: true,
|
||||||
|
handler(value) {
|
||||||
|
this.layout.setMaxHeight(value);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
currentRowKey(newVal) {
|
currentRowKey(newVal) {
|
||||||
|
@ -488,8 +556,8 @@
|
||||||
|
|
||||||
data: {
|
data: {
|
||||||
immediate: true,
|
immediate: true,
|
||||||
handler(val) {
|
handler(value) {
|
||||||
this.store.commit('setData', val);
|
this.store.commit('setData', value);
|
||||||
if (this.$ready) {
|
if (this.$ready) {
|
||||||
this.$nextTick(() => {
|
this.$nextTick(() => {
|
||||||
this.doLayout();
|
this.doLayout();
|
||||||
|
@ -509,13 +577,19 @@
|
||||||
},
|
},
|
||||||
|
|
||||||
destroyed() {
|
destroyed() {
|
||||||
if (this.windowResizeListener) removeResizeListener(this.$el, this.windowResizeListener);
|
if (this.resizeListener) removeResizeListener(this.$el, this.resizeListener);
|
||||||
},
|
},
|
||||||
|
|
||||||
mounted() {
|
mounted() {
|
||||||
this.bindEvents();
|
this.bindEvents();
|
||||||
|
this.store.updateColumns();
|
||||||
this.doLayout();
|
this.doLayout();
|
||||||
|
|
||||||
|
this.resizeState = {
|
||||||
|
width: this.$el.offsetWidth,
|
||||||
|
height: this.$el.offsetHeight
|
||||||
|
};
|
||||||
|
|
||||||
// init filters
|
// init filters
|
||||||
this.store.states.columns.forEach(column => {
|
this.store.states.columns.forEach(column => {
|
||||||
if (column.filteredValue && column.filteredValue.length) {
|
if (column.filteredValue && column.filteredValue.length) {
|
||||||
|
@ -542,11 +616,15 @@
|
||||||
showHeader: this.showHeader
|
showHeader: this.showHeader
|
||||||
});
|
});
|
||||||
return {
|
return {
|
||||||
store,
|
|
||||||
layout,
|
layout,
|
||||||
|
store,
|
||||||
isHidden: false,
|
isHidden: false,
|
||||||
renderExpanded: null,
|
renderExpanded: null,
|
||||||
resizeProxyVisible: false,
|
resizeProxyVisible: false,
|
||||||
|
resizeState: {
|
||||||
|
width: null,
|
||||||
|
height: null
|
||||||
|
},
|
||||||
// 是否拥有多级表头
|
// 是否拥有多级表头
|
||||||
isGroup: false,
|
isGroup: false,
|
||||||
scrollPosition: 'left'
|
scrollPosition: 'left'
|
||||||
|
|
|
@ -83,6 +83,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@include m(scrollable-x) {
|
||||||
|
.el-table__body-wrapper {
|
||||||
|
overflow-x: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@include m(scrollable-y) {
|
||||||
|
.el-table__body-wrapper {
|
||||||
|
overflow-y: auto;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
thead {
|
thead {
|
||||||
color: $--table-header-color;
|
color: $--table-header-color;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
@ -296,6 +308,7 @@
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
overflow-y: hidden;
|
||||||
box-shadow: $--table-fixed-box-shadow;
|
box-shadow: $--table-fixed-box-shadow;
|
||||||
|
|
||||||
&::before {
|
&::before {
|
||||||
|
@ -372,6 +385,7 @@
|
||||||
|
|
||||||
@include e((header, body, footer)) {
|
@include e((header, body, footer)) {
|
||||||
table-layout: fixed;
|
table-layout: fixed;
|
||||||
|
border-collapse: separate;
|
||||||
}
|
}
|
||||||
|
|
||||||
@include e((header-wrapper, footer-wrapper)) {
|
@include e((header-wrapper, footer-wrapper)) {
|
||||||
|
@ -384,36 +398,36 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@include e(body-wrapper) {
|
@include e(body-wrapper) {
|
||||||
overflow: auto;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
@include when(scroll-none) {
|
@include when(scrolling-none) {
|
||||||
~ .el-table__fixed,
|
~ .el-table__fixed,
|
||||||
~ .el-table__fixed-right {
|
~ .el-table__fixed-right {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include when(scroll-left) {
|
@include when(scrolling-left) {
|
||||||
~ .el-table__fixed {
|
~ .el-table__fixed {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include when(scroll-right) {
|
@include when(scrolling-right) {
|
||||||
~ .el-table__fixed-right {
|
~ .el-table__fixed-right {
|
||||||
box-shadow: none;
|
box-shadow: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.el-table--border {
|
.el-table--border {
|
||||||
@include when(scroll-right) {
|
@include when(scrolling-right) {
|
||||||
~ .el-table__fixed-right {
|
~ .el-table__fixed-right {
|
||||||
border-left: $--table-border;
|
border-left: $--table-border;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@include when(scroll-left) {
|
@include when(scrolling-left) {
|
||||||
~ .el-table__fixed {
|
~ .el-table__fixed {
|
||||||
border-right: $--table-border;
|
border-right: $--table-border;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue