浏览代码

Table: support manually sorting. Resolves #9495 (#11311)

* Table: support manually sorting. Resolves #9495

* Table: add parameters for sort api

* Docs: improve docs
Jikkai Xiao 7 年之前
父节点
当前提交
f18bbeb473

+ 2 - 1
examples/docs/en-US/table.md

@@ -2007,7 +2007,8 @@ You can customize row index in `type=index` columns.
 | setCurrentRow | used in single selection Table, set a certain row selected. If called without any parameter, it will clear selection. | row |
 | clearSort | clear sorting, restore data to the original order | — |
 | clearFilter | clear filter | — |
-| doLayout | Refresh the layout of Table. When the visibility of Table changes, you may need to call this method to get a correct layout | — |
+| doLayout | refresh the layout of Table. When the visibility of Table changes, you may need to call this method to get a correct layout | — |
+| sort | sort Table manually. Property `prop` is used to set sort column, property `order` is used to set sort order | prop: string, order: string |
 
 ### Table Slot
 | Name | Description |

+ 2 - 0
examples/docs/es/table.md

@@ -2010,6 +2010,8 @@ Puede personalizar el índice de la fila con la propiedad `type=index` de las co
 | setCurrentRow      | utilizado en tabla con selección sencilla, establece una cierta fila seleccionada. Si es llamado sin ningún parámetro, este puede limpiar la selección | row           |
 | clearSort          | limpiar ordenamiento, restaurar datos a orden original | —             |
 | clearFilter        | limpiar filtros                          | —             |
+| doLayout | refresh the layout of Table. When the visibility of Table changes, you may need to call this method to get a correct layout | — |
+| sort | sort Table manually. Property `prop` is used to set sort column, property `order` is used to set sort order | prop: string, order: string |
 
 ### Slots de la tabla
 | Nombre | Descripción                              |

+ 2 - 1
examples/docs/zh-CN/table.md

@@ -2029,7 +2029,7 @@
 | empty-text | 空数据时显示的文本内容,也可以通过 `slot="empty"` 设置 | String | — | 暂无数据 |
 | default-expand-all | 是否默认展开所有行,当 Table 中存在 type="expand" 的 Column 的时候有效 | Boolean | — | false |
 | expand-row-keys | 可以通过该属性设置 Table 目前的展开行,需要设置 row-key 属性才能使用,该属性为展开行的 keys 数组。| Array | — | |
-| default-sort | 默认的排序列的prop和顺序。它的`prop`属性指定默认的排序的列,`order`指定默认排序的顺序| Object | `order`: ascending, descending | 如果只指定了`prop`, 没有指定`order`, 则默认顺序是ascending |
+| default-sort | 默认的排序列的 prop 和顺序。它的`prop`属性指定默认的排序的列,`order`指定默认排序的顺序| Object | `order`: ascending, descending | 如果只指定了`prop`, 没有指定`order`, 则默认顺序是ascending |
 | tooltip-effect | tooltip `effect` 属性 | String | dark/light | | dark |
 | show-summary | 是否在表尾显示合计行 | Boolean | — | false |
 | sum-text | 合计行第一列的文本 | String | — | 合计 |
@@ -2068,6 +2068,7 @@
 | clearSort | 用于清空排序条件,数据会恢复成未排序的状态 | — |
 | clearFilter | 用于清空过滤条件,数据会恢复成未过滤的状态 | — |
 | doLayout | 对 Table 进行重新布局。当 Table 或其祖先元素由隐藏切换为显示时,可能需要调用此方法 | — |
+| sort | 手动对 Table 进行排序。参数`prop`属性指定排序列,`order`指定排序顺序。 | prop: string, order: string |
 
 ### Table Slot
 | name | 说明 |

+ 2 - 19
packages/table/src/table-header.js

@@ -208,25 +208,8 @@ export default {
   },
 
   mounted() {
-    if (this.defaultSort.prop) {
-      const states = this.store.states;
-      states.sortProp = this.defaultSort.prop;
-      states.sortOrder = this.defaultSort.order || 'ascending';
-      this.$nextTick(_ => {
-        for (let i = 0, length = this.columns.length; i < length; i++) {
-          let column = this.columns[i];
-          if (column.property === states.sortProp) {
-            column.order = states.sortOrder;
-            states.sortingColumn = column;
-            break;
-          }
-        }
-
-        if (states.sortingColumn) {
-          this.store.commit('changeSortCondition');
-        }
-      });
-    }
+    const { prop, order } = this.defaultSort;
+    this.store.commit('sort', { prop, order });
   },
 
   beforeDestroy() {

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

@@ -203,6 +203,28 @@ TableStore.prototype.mutations = {
     Vue.nextTick(() => this.table.updateScrollY());
   },
 
+  sort(states, options) {
+    const { prop, order } = options;
+    if (prop) {
+      states.sortProp = prop;
+      states.sortOrder = order || 'ascending';
+      Vue.nextTick(() => {
+        for (let i = 0, length = states.columns.length; i < length; i++) {
+          let column = states.columns[i];
+          if (column.property === states.sortProp) {
+            column.order = states.sortOrder;
+            states.sortingColumn = column;
+            break;
+          }
+        }
+
+        if (states.sortingColumn) {
+          this.commit('changeSortCondition');
+        }
+      });
+    }
+  },
+
   filterChange(states, options) {
     let { column, values, silent } = options;
     if (values && !Array.isArray(values)) {

+ 4 - 0
packages/table/src/table.vue

@@ -443,6 +443,10 @@
         if (this.shouldUpdateHeight) {
           this.layout.updateElsHeight();
         }
+      },
+
+      sort(prop, order) {
+        this.store.commit('sort', { prop, order });
       }
     },
 

+ 37 - 0
test/unit/specs/table.spec.js

@@ -1709,6 +1709,43 @@ describe('Table', () => {
 
       destroyVM(vm);
     });
+
+    it('sort', done => {
+      const vm = createVue({
+        template: `
+          <el-table ref="table" :data="testData" :default-sort = "{prop: 'runtime', order: 'ascending'}">
+            <el-table-column prop="name" />
+            <el-table-column prop="release" />
+            <el-table-column prop="director" />
+            <el-table-column prop="runtime"/>
+          </el-table>
+        `,
+
+        created() {
+          this.testData = getTestData();
+        },
+
+        data() {
+          return { testData: this.testData };
+        }
+      });
+
+      setTimeout(() => {
+        const lastCells = vm.$el.querySelectorAll('.el-table__body-wrapper tbody tr td:last-child');
+        expect(toArray(lastCells).map(node => node.textContent))
+          .to.eql(['80', '92', '92', '95', '100']);
+
+        vm.$nextTick(() => {
+          vm.testData = vm.testData.map(data => Object.assign(data, { runtime: -data.runtime }));
+          vm.$refs.table.sort('runtime', 'ascending');
+          vm.$nextTick(() => {
+            expect(toArray(lastCells).map(node => node.textContent))
+              .to.eql(['-100', '-95', '-92', '-92', '-80']);
+            done();
+          });
+        });
+      }, DELAY);
+    });
   });
 
   it('hover', done => {

+ 3 - 0
types/table.d.ts

@@ -116,4 +116,7 @@ export declare class ElTable extends ElementUIComponent {
 
   /** Relayout the table, maybe needed when change the table or it's ancestors visibility */
   doLayout (): void
+
+  /** Sort Table manually */
+  sort (prop: string, order: string): void
 }