Forráskód Böngészése

Table: improve performance in large data. (#1298)

FuryBean 8 éve
szülő
commit
631037c296

+ 7 - 17
packages/table/src/table-body.js

@@ -1,4 +1,4 @@
-import { getValueByPath, getCell, getColumnByCell, getRowIdentity } from './util';
+import { getCell, getColumnByCell, getRowIdentity } from './util';
 
 export default {
   props: {
@@ -15,6 +15,7 @@ export default {
   },
 
   render(h) {
+    const columnsHidden = this.columns.map((column, index) => this.isColumnHidden(index));
     return (
       <table
         class="el-table__body"
@@ -40,7 +41,7 @@ export default {
                 {
                   this._l(this.columns, (column, cellIndex) =>
                     <td
-                      class={ [column.id, column.align, column.className || '', this.isCellHidden(cellIndex) ? 'is-hidden' : '' ] }
+                      class={ [column.id, column.align, column.className || '', columnsHidden[cellIndex] ? 'is-hidden' : '' ] }
                       on-mouseenter={ ($event) => this.handleCellMouseEnter($event, row) }
                       on-mouseleave={ this.handleCellMouseLeave }>
                       {
@@ -62,9 +63,10 @@ export default {
 
   watch: {
     'store.states.hoverRow'(newVal, oldVal) {
+      if (!this.store.states.isComplex) return;
       const el = this.$el;
       if (!el) return;
-      const rows = el.querySelectorAll('tr');
+      const rows = el.querySelectorAll('tbody > tr');
       const oldRow = rows[oldVal];
       const newRow = rows[newVal];
       if (oldRow) {
@@ -79,7 +81,7 @@ export default {
       const el = this.$el;
       if (!el) return;
       const data = this.store.states.data;
-      const rows = el.querySelectorAll('tr');
+      const rows = el.querySelectorAll('tbody > tr');
       const oldRow = rows[data.indexOf(oldVal)];
       const newRow = rows[data.indexOf(newVal)];
       if (oldRow) {
@@ -128,7 +130,7 @@ export default {
       return index;
     },
 
-    isCellHidden(index) {
+    isColumnHidden(index) {
       if (this.fixed === true || this.fixed === 'left') {
         return index >= this.leftFixedCount;
       } else if (this.fixed === 'right') {
@@ -197,18 +199,6 @@ export default {
       this.store.commit('setCurrentRow', row);
 
       table.$emit('row-click', row, event);
-    },
-
-    getCellContent(row, property, column) {
-      if (column && column.formatter) {
-        return column.formatter(row, column);
-      }
-
-      if (property && property.indexOf('.') === -1) {
-        return row[property];
-      }
-
-      return getValueByPath(row, property);
     }
   }
 };

+ 20 - 6
packages/table/src/table-column.js

@@ -1,6 +1,7 @@
 import ElCheckbox from 'element-ui/packages/checkbox';
 import ElTag from 'element-ui/packages/tag';
 import objectAssign from 'element-ui/src/utils/merge';
+import { getValueByPath } from './util';
 
 let columnIdSeed = 1;
 
@@ -72,8 +73,17 @@ const getDefaultColumn = function(type, options) {
   return column;
 };
 
-const DEFAULT_RENDER_CELL = function(h, { row, column }, parent) {
-  return parent.getCellContent(row, column.property, column);
+const DEFAULT_RENDER_CELL = function(h, { row, column }) {
+  const property = column.property;
+  if (column && column.formatter) {
+    return column.formatter(row, column);
+  }
+
+  if (property && property.indexOf('.') === -1) {
+    return row[property];
+  }
+
+  return getValueByPath(row, property);
 };
 
 export default {
@@ -182,7 +192,7 @@ export default {
       className: this.className,
       property: this.prop || this.property,
       type,
-      renderCell: DEFAULT_RENDER_CELL,
+      renderCell: null,
       renderHeader: this.renderHeader,
       minWidth,
       width,
@@ -229,15 +239,19 @@ export default {
         };
       }
 
+      if (!renderCell) {
+        renderCell = DEFAULT_RENDER_CELL;
+      }
+
       return _self.showOverflowTooltip || _self.showTooltipWhenOverflow
         ? <el-tooltip
             effect={ this.effect }
             placement="top"
             disabled={ this.tooltipDisabled }>
-            <div class="cell">{ renderCell(h, data, this._renderProxy) }</div>
-            <span slot="content">{ renderCell(h, data, this._renderProxy) }</span>
+            <div class="cell">{ renderCell(h, data) }</div>
+            <span slot="content">{ renderCell(h, data) }</span>
           </el-tooltip>
-        : <div class="cell">{ renderCell(h, data, this._renderProxy) }</div>;
+        : <div class="cell">{ renderCell(h, data) }</div>;
     };
 
     this.columnConfig = column;

+ 2 - 0
packages/table/src/table-layout.js

@@ -42,6 +42,8 @@ class TableLayout {
   }
 
   updateScrollY() {
+    const height = this.height;
+    if (typeof height !== 'string' || typeof height !== 'number') return;
     const bodyWrapper = this.table.$refs.bodyWrapper;
     if (this.table.$el && bodyWrapper) {
       const body = bodyWrapper.querySelector('.el-table__body');

+ 2 - 0
packages/table/src/table-store.js

@@ -55,6 +55,7 @@ const TableStore = function(table, initialState = {}) {
     columns: [],
     fixedColumns: [],
     rightFixedColumns: [],
+    isComplex: false,
     _data: null,
     filteredData: null,
     data: null,
@@ -246,6 +247,7 @@ TableStore.prototype.updateColumns = function() {
     states.fixedColumns.unshift(_columns[0]);
   }
   states.columns = [].concat(states.fixedColumns).concat(_columns.filter((column) => !column.fixed)).concat(states.rightFixedColumns);
+  states.isComplex = states.fixedColumns.length > 0 || states.rightFixedColumns.length > 0;
 };
 
 TableStore.prototype.isSelected = function(row) {

+ 7 - 1
packages/table/src/table.vue

@@ -1,6 +1,12 @@
 <template>
   <div class="el-table"
-    :class="{ 'el-table--fit': fit, 'el-table--striped': stripe, 'el-table--border': border }"
+    :class="{
+      'el-table--fit': fit,
+      'el-table--striped': stripe,
+      'el-table--border': border,
+      'el-table--enable-row-hover': !store.states.isComplex,
+      'el-table--enable-row-transition': true || (store.states.data || []).length !== 0 && (store.states.data || []).length < 100
+    }"
     @mouseleave="handleMouseLeave($event)">
     <div class="hidden-columns" ref="hiddenColumns"><slot></slot></div>
     <div class="el-table__header-wrapper" ref="headerWrapper" v-if="showHeader">

+ 14 - 6
packages/theme-default/src/table.css

@@ -325,15 +325,11 @@
     }
 
     @e body {
-      td {
-        transition: background-color .25s ease;
-      }
-
-      tr.hover-row td {
+      tr.hover-row > td {
         background-color: #eff2f7;
       }
 
-      tr.current-row td {
+      tr.current-row > td {
         background: #eff7ff;
       }
     }
@@ -364,5 +360,17 @@
         color: #99a9bf;
       }
     }
+
+    @modifier enable-row-transition {
+      .el-table__body td {
+        transition: background-color .25s ease;
+      }
+    }
+
+    @modifier enable-row-hover {
+      tr:hover > td {
+        background-color: #eff2f7;
+      }
+    }
   }
 }

+ 1 - 1
test/unit/specs/table.spec.js

@@ -1054,7 +1054,7 @@ describe('Table', () => {
     const vm = createVue({
       template: `
         <el-table :data="testData">
-          <el-table-column prop="name" label="片名" />
+          <el-table-column prop="name" label="片名" fixed />
           <el-table-column prop="release" label="发行日期" />
           <el-table-column prop="director" label="导演" />
           <el-table-column prop="runtime" label="时长(分)" />