From 3e704f9e2ff32d1357cd80a542f2feb15d7955c7 Mon Sep 17 00:00:00 2001 From: wangxueliang Date: Tue, 30 Apr 2019 16:59:53 +0800 Subject: [PATCH] feat: update table --- components/table/Table.jsx | 199 +++++++++++------- components/table/demo/basic.md | 8 +- components/table/demo/custom-filter-panel.md | 8 +- components/table/demo/fixed-columns-header.md | 4 +- components/table/demo/fixed-columns.md | 4 +- components/table/demo/fixed-header.md | 4 +- components/table/demo/head.md | 4 + components/table/demo/index.vue | 21 +- components/table/filterDropdown.jsx | 2 +- components/table/index.en-US.md | 10 +- components/table/index.zh-CN.md | 12 +- components/table/interface.js | 4 +- 12 files changed, 162 insertions(+), 118 deletions(-) diff --git a/components/table/Table.jsx b/components/table/Table.jsx index f469867fc..0bc0b606f 100755 --- a/components/table/Table.jsx +++ b/components/table/Table.jsx @@ -24,6 +24,7 @@ import { getAllProps, } from '../_util/props-util'; import BaseMixin from '../_util/BaseMixin'; +import { ConfigConsumerProps } from '../config-provider'; import { TableProps } from './interface'; function noop() {} @@ -44,6 +45,8 @@ const defaultPagination = { onShowSizeChange: noop, }; +const ROW_SELECTION_COLUMN_WIDTH = '62px'; + /** * Avoid creating new object, so that parent component's shouldComponentUpdate * can works appropriately。 @@ -57,7 +60,6 @@ export default { mixins: [BaseMixin], props: initDefaultProps(TableProps, { dataSource: [], - prefixCls: 'ant-table', useFixedHeader: false, // rowSelection: null, size: 'default', @@ -67,8 +69,12 @@ export default { locale: {}, rowKey: 'key', showHeader: true, + sortDirections: ['ascend', 'descend'], }), + inject: { + configProvider: { default: () => ({}) }, + }, // CheckboxPropsCache: { // [key: string]: any; // }; @@ -86,6 +92,7 @@ export default { selectedRowKeys: getRowSelection(this.$props).selectedRowKeys || [], selectionDirty: false, }); + this.prevRowSelection = this.rowSelection ? {...this.rowSelection} : this.rowSelection; return { ...this.getDefaultSortOrder(this.columns), // 减少状态 @@ -120,7 +127,12 @@ export default { if (rowSelection && val.getCheckboxProps !== rowSelection.getCheckboxProps) { this.CheckboxPropsCache = {}; } + } else if(val && !this.prevRowSelection) { + this.store.setState({ + selectedRowKeys: [], + }); } + this.prevRowSelection = val ? {...val} : val; }, deep: true, }, @@ -185,19 +197,31 @@ export default { }, getDefaultPagination(props) { - const pagination = props.pagination || {}; + const pagination = typeof props.pagination === 'object' ? props.pagination : {}; + let current; + if ('current' in pagination) { + current = pagination.current; + } else if ('defaultCurrent' in pagination) { + current = pagination.defaultCurrent; + } + let pageSize; + if ('pageSize' in pagination) { + pageSize = pagination.pageSize; + } else if ('defaultPageSize' in pagination) { + pageSize = pagination.defaultPageSize; + } return this.hasPagination(props) ? { ...defaultPagination, ...pagination, - current: pagination.defaultCurrent || pagination.current || 1, - pageSize: pagination.defaultPageSize || pagination.pageSize || 10, + current: current || 1, + pageSize: pageSize || 10, } : {}; }, - onRow(record, index) { - const { prefixCls, customRow } = this; + onRow(prefixCls, record, index) { + const { customRow } = this; const custom = customRow ? customRow(record, index) : {}; return mergeProps(custom, { props: { @@ -346,18 +370,18 @@ export default { if (!column.sorter) { return; } + const sortDirections = column.sortDirections || this.sortDirections; const { sSortOrder: sortOrder, sSortColumn: sortColumn } = this; // 只同时允许一列进行排序,否则会导致排序顺序的逻辑问题 let newSortOrder; // 切换另一列时,丢弃 sortOrder 的状态 - const oldSortOrder = this.isSameColumn(sortColumn, column) ? sortOrder : undefined; - // 切换排序状态,按照降序/升序/不排序的顺序 - if (!oldSortOrder) { - newSortOrder = 'ascend'; - } else if (oldSortOrder === 'ascend') { - newSortOrder = 'descend'; + if (this.isSameColumn(sortColumn, column) && sortOrder !== undefined) { + // 按照sortDirections的内容依次切换排序状态 + const methodIndex = sortDirections.indexOf(sortOrder) + 1; + newSortOrder = + methodIndex === sortDirections.length ? undefined : sortDirections[methodIndex]; } else { - newSortOrder = undefined; + newSortOrder = sortDirections[0]; } const newState = { sSortOrder: newSortOrder, @@ -683,8 +707,15 @@ export default { return this.$el; }, - renderRowSelection(locale) { - const { prefixCls, rowSelection, childrenColumnName } = this; + generatePopupContainerFunc() { + const { scroll } = this.$props; + + // Use undefined to let rc component use default logic. + return scroll ? this.getPopupContainer : undefined; + }, + + renderRowSelection(prefixCls, locale) { + const { rowSelection, childrenColumnName } = this; const columns = this.columns.concat(); if (rowSelection) { const data = this.getFlatCurrentPageData(childrenColumnName).filter((item, index) => { @@ -701,7 +732,7 @@ export default { customRender: this.renderSelectionBox(rowSelection.type), className: selectionColumnClass, fixed: rowSelection.fixed, - width: rowSelection.columnWidth, + width: rowSelection.columnWidth || ROW_SELECTION_COLUMN_WIDTH, title: rowSelection.columnTitle, }; if (rowSelection.type !== 'radio') { @@ -720,7 +751,7 @@ export default { onSelect={this.handleSelectRow} selections={rowSelection.selections} hideDefaultSelections={rowSelection.hideDefaultSelections} - getPopupContainer={this.getPopupContainer} + getPopupContainer={this.generatePopupContainerFunc()} /> ); } @@ -758,15 +789,14 @@ export default { return this.getColumnKey(sortColumn) === this.getColumnKey(column); }, - renderColumnsDropdown(columns, locale) { - const { prefixCls, dropdownPrefixCls } = this; + renderColumnsDropdown(prefixCls, dropdownPrefixCls, columns, locale) { const { sSortOrder: sortOrder, sFilters: filters } = this; return treeMap(columns, (column, i) => { const key = this.getColumnKey(column, i); let filterDropdown; let sortButton; let customHeaderCell = column.customHeaderCell; - const sortTitle = this.getColumnTitle(column.title, {}) || locale.sortTitle; + // const sortTitle = this.getColumnTitle(column.title, {}) || locale.sortTitle; const isSortColumn = this.isSortColumn(column); if ((column.filters && column.filters.length > 0) || column.filterDropdown) { const colFilters = key in filters ? filters[key] : []; @@ -779,26 +809,34 @@ export default { confirmFilter={this.handleFilter} prefixCls={`${prefixCls}-filter`} dropdownPrefixCls={dropdownPrefixCls || 'ant-dropdown'} - getPopupContainer={this.getPopupContainer} + getPopupContainer={this.generatePopupContainerFunc()} key="filter-dropdown" /> ); } if (column.sorter) { + const sortDirections = column.sortDirections || this.sortDirections; const isAscend = isSortColumn && sortOrder === 'ascend'; const isDescend = isSortColumn && sortOrder === 'descend'; + const ascend = sortDirections.indexOf('ascend') !== -1 && ( + + ); + + const descend = sortDirections.indexOf('descend') !== -1 && ( + + ); sortButton = ( -
- - +
+ {ascend} + {descend}
); customHeaderCell = col => { @@ -821,7 +859,7 @@ export default { return colProps; }; } - const sortTitleString = sortButton && typeof sortTitle === 'string' ? sortTitle : undefined; + // const sortTitleString = sortButton && typeof sortTitle === 'string' ? sortTitle : undefined; return { ...column, className: classNames(column.className, { @@ -833,7 +871,6 @@ export default { title: [
{this.renderColumnTitle(column.title)} @@ -857,33 +894,33 @@ export default { return title; }, - getColumnTitle(title, parentNode) { - if (!title) { - return; - } - if (isValidElement(title)) { - const props = title.componentOptions; - let children = null; - if (props && props.children) { - // for component - children = filterEmpty(props.children); - } else if (title.children) { - // for dom - children = filterEmpty(title.children); - } - if (children && children.length === 1) { - children = children[0]; - const attrs = getAllProps(title); - if (!children.tag && children.text) { - // for textNode - children = children.text; - } - return this.getColumnTitle(children, attrs); - } - } else { - return parentNode.title || title; - } - }, + // getColumnTitle(title, parentNode) { + // if (!title) { + // return; + // } + // if (isValidElement(title)) { + // const props = title.componentOptions; + // let children = null; + // if (props && props.children) { + // // for component + // children = filterEmpty(props.children); + // } else if (title.children) { + // // for dom + // children = filterEmpty(title.children); + // } + // if (children && children.length === 1) { + // children = children[0]; + // const attrs = getAllProps(title); + // if (!children.tag && children.text) { + // // for textNode + // children = children.text; + // } + // return this.getColumnTitle(children, attrs); + // } + // } else { + // return parentNode.title || title; + // } + // }, handleShowSizeChange(current, pageSize) { const pagination = this.sPagination; @@ -903,7 +940,7 @@ export default { ); }, - renderPagination(paginationPosition) { + renderPagination(prefixCls, paginationPosition) { // 强制不需要分页 if (!this.hasPagination()) { return null; @@ -920,7 +957,7 @@ export default { const { class: cls, style, onChange, onShowSizeChange, ...restProps } = pagination; // eslint-disable-line const paginationProps = mergeProps({ key: `pagination-${paginationPosition}`, - class: classNames(cls, `${this.prefixCls}-pagination`), + class: classNames(cls, `${prefixCls}-pagination`), props: { ...restProps, total, @@ -1063,12 +1100,17 @@ export default { }; }, - renderTable(contextLocale, loading) { + renderTable(prefixCls, renderEmpty, dropdownPrefixCls, contextLocale, loading) { const locale = { ...contextLocale, ...this.locale }; - const { prefixCls, showHeader, ...restProps } = getOptionProps(this); + const { showHeader, ...restProps } = getOptionProps(this); const data = this.getCurrentPageData(); const expandIconAsCell = this.expandedRowRender && this.expandIconAsCell !== false; + const mergedLocale = { ...contextLocale, ...locale }; + if (!locale || !locale.emptyText) { + mergedLocale.emptyText = renderEmpty(h, 'Table'); + } + const classString = classNames({ [`${prefixCls}-${this.size}`]: true, [`${prefixCls}-bordered`]: this.bordered, @@ -1076,8 +1118,8 @@ export default { [`${prefixCls}-without-column-header`]: !showHeader, }); - let columns = this.renderRowSelection(locale); - columns = this.renderColumnsDropdown(columns, locale); + let columns = this.renderRowSelection(prefixCls, mergedLocale); + columns = this.renderColumnsDropdown(prefixCls, dropdownPrefixCls, columns, mergedLocale); columns = columns.map((column, i) => { const newColumn = { ...column }; newColumn.key = this.getColumnKey(newColumn, i); @@ -1091,7 +1133,7 @@ export default { key: 'table', props: { ...restProps, - customRow: this.onRow, + customRow: (record, index) => this.onRow(prefixCls, record, index), components: this.customComponents, prefixCls, data, @@ -1099,7 +1141,7 @@ export default { showHeader, expandIconColumnIndex, expandIconAsCell, - emptyText: !(loading.props && loading.props.spinning) && locale.emptyText, + emptyText: !(loading.props && loading.props.spinning) && mergedLocale.emptyText, }, on: this.$listeners, class: classString, @@ -1109,7 +1151,10 @@ export default { }, render() { - const { prefixCls } = this; + const { + prefixCls: customizePrefixCls, + dropdownPrefixCls: customizeDropdownPrefixCls, + } = this; const data = this.getCurrentPageData(); let loading = this.loading; @@ -1124,12 +1169,20 @@ export default { props: { ...loading }, }; } + const getPrefixCls = this.configProvider.getPrefixCls || ConfigConsumerProps.getPrefixCls; + const renderEmpty = ( + this.configProvider.renderEmpty && + this.configProvider.renderEmpty() + ) || ConfigConsumerProps.renderEmpty; + + const prefixCls = getPrefixCls('table', customizePrefixCls); + const dropdownPrefixCls = getPrefixCls('dropdown', customizeDropdownPrefixCls); const table = ( this.renderTable(locale, loading)} + children={locale => this.renderTable(prefixCls, renderEmpty, dropdownPrefixCls, locale, loading)} /> ); @@ -1149,9 +1202,9 @@ export default { return (
- {this.renderPagination('top')} + {this.renderPagination(prefixCls, 'top')} {table} - {this.renderPagination('bottom')} + {this.renderPagination(prefixCls, 'bottom')}
); diff --git a/components/table/demo/basic.md b/components/table/demo/basic.md index 45255a1b7..b5690cb77 100644 --- a/components/table/demo/basic.md +++ b/components/table/demo/basic.md @@ -14,7 +14,13 @@ Simple table with actions. {{text}} Name - {{tag}} + + {{tag.toUpperCase()}} + Invite 一 {{record.name}} diff --git a/components/table/demo/custom-filter-panel.md b/components/table/demo/custom-filter-panel.md index 9d4966300..30e6fcc7b 100644 --- a/components/table/demo/custom-filter-panel.md +++ b/components/table/demo/custom-filter-panel.md @@ -11,7 +11,7 @@ Implement a customized column search example via `filterDropdown`. ```html