diff --git a/examples/table/demos/editable-row.vue b/examples/table/demos/editable-row.vue index 20710066b..f1e051f01 100644 --- a/examples/table/demos/editable-row.vue +++ b/examples/table/demos/editable-row.vue @@ -202,50 +202,69 @@ export default { const { id } = e.currentTarget.dataset; this.currentSaveId = id; // 触发内部校验,而后在 onRowValidate 中接收异步校验结果 - this.$refs.tableRef.validateRowData(id); + this.$refs.tableRef.validateRowData(id).then((params) => { + console.log('Event Table Promise Validate:', params); + if (params.result.length) { + const r = params.result[0]; + MessagePlugin.error(`${r.col.title} ${r.errorList[0].message}`); + return; + } + // 如果是 table 的父组件主动触发校验 + if (params.trigger === 'parent' && !params.result.length) { + const current = this.editMap[this.currentSaveId]; + if (current) { + this.data.splice(current.rowIndex, 1, current.editedRow); + MessagePlugin.success('保存成功'); + } + this.updateEditState(this.currentSaveId); + } + }); }, // 行校验反馈事件,this.$refs.tableRef.validateRowData 执行结束后触发 onRowValidate(params) { - console.log('row-validate:', params); - if (params.result.length) { - const r = params.result[0]; - MessagePlugin.error(`${r.col.title} ${r.errorList[0].message}`); - return; - } - // 如果是 table 的父组件主动触发校验 - if (params.trigger === 'parent' && !params.result.length) { - const current = this.editMap[this.currentSaveId]; - if (current) { - this.data.splice(current.rowIndex, 1, current.editedRow); - MessagePlugin.success('保存成功'); - } - this.updateEditState(this.currentSaveId); - } + console.log('Event Table Row Validate:', params); }, onValidateTableData() { // 执行结束后触发事件 validate - this.$refs.tableRef.validateTableData(); + this.$refs.tableRef.validateTableData().then((params) => { + console.log('Promise Table Data Validate:', params); + const cellKeys = Object.keys(params.result); + const firstError = params.result[cellKeys[0]]; + if (firstError) { + MessagePlugin.warning(firstError[0].message); + } + }); }, // 表格全量数据校验反馈事件,this.$refs.tableRef.validateTableData() 执行结束后触发 onValidate(params) { - console.log('validate:', params); - const cellKeys = Object.keys(params.result); - const firstError = params.result[cellKeys[0]]; - if (firstError) { - MessagePlugin.warning(firstError[0].message); - } + console.log('Event Table Data Validate:', params); }, onRowEdit(params) { - const { row, col, value } = params; + // eslint-disable-next-line @typescript-eslint/no-unused-vars + const { + row, + // eslint-disable-next-line @typescript-eslint/no-unused-vars + rowIndex, + col, + value, + } = params; const oldRowData = this.editMap[row.key]?.editedRow || row; + const editedRow = { ...oldRowData, [col.colKey]: value }; this.editMap[row.key] = { ...params, - editedRow: { ...oldRowData, [col.colKey]: value }, + editedRow, }; + + // ⚠️ 重要:以下内容应用于全量数据校验(单独的行校验不需要) + // const newData = [...this.data]; + // newData[rowIndex] = editedRow; + // this.data = newData; + // 或者 + // this.$set(this.data, rowIndex, editedRow); }, }, }; diff --git a/examples/table/table.en-US.md b/examples/table/table.en-US.md index 8b4949112..13873bae6 100644 --- a/examples/table/table.en-US.md +++ b/examples/table/table.en-US.md @@ -8,7 +8,7 @@ name | type | default | description | required allowResizeColumnWidth | Boolean | undefined | `deprecated`。allow to resize column width | N bordered | Boolean | false | show table bordered | N bottomContent | String / Slot / Function | - | Typescript:`string | TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N -cellEmptyContent | String / Slot / Function | '' | empty cell content。Typescript:`string | TNode>`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N +cellEmptyContent | String / Slot / Function | - | Typescript:`string | TNode>`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N columns | Array | [] | table column configs。Typescript:`Array>` | N data | Array | [] | table data。Typescript:`Array` | N disableDataPage | Boolean | false | \- | N @@ -43,18 +43,18 @@ tableContentWidth | String | - | \- | N tableLayout | String | fixed | table-layout css properties。options:auto/fixed | N topContent | String / Slot / Function | - | Typescript:`string | TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N verticalAlign | String | middle | vertical align。options:top/middle/bottom | N -onCellClick | Function | | TS 类型:`(context: BaseTableCellEventContext) => void`
trigger on cell clicked。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface BaseTableCellEventContext { row: T; col: BaseTableCol; rowIndex: number; colIndex: number; e: MouseEvent }`
| N -onPageChange | Function | | TS 类型:`(pageInfo: PageInfo, newDataSource: Array) => void`
trigger on pagination changing | N -onRowClick | Function | | TS 类型:`(context: RowEventContext) => void`
trigger on row click。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface RowEventContext { row: T; index: number; e: MouseEvent }`
| N -onRowDblclick | Function | | TS 类型:`(context: RowEventContext) => void`
trigger on double click | N -onRowMousedown | Function | | TS 类型:`(context: RowEventContext) => void`
trigger on row mousedown | N -onRowMouseenter | Function | | TS 类型:`(context: RowEventContext) => void`
trigger on row mouseenter | N -onRowMouseleave | Function | | TS 类型:`(context: RowEventContext) => void`
trigger on row mouseenter | N -onRowMouseover | Function | | TS 类型:`(context: RowEventContext) => void`
trigger on row mouseover | N -onRowMouseup | Function | | TS 类型:`(context: RowEventContext) => void`
trigger on row mouseup | N -onScroll | Function | | TS 类型:`(params: { e: WheelEvent }) => void`
trigger on table content scroll | N -onScrollX | Function | | TS 类型:`(params: { e: WheelEvent }) => void`
`deprecated`。trigger on scroll horizontal | N -onScrollY | Function | | TS 类型:`(params: { e: WheelEvent }) => void`
`deprecated`。trigger on scroll vertical | N +onCellClick | Function | | Typescript:`(context: BaseTableCellEventContext) => void`
trigger on cell clicked。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface BaseTableCellEventContext { row: T; col: BaseTableCol; rowIndex: number; colIndex: number; e: MouseEvent }`
| N +onPageChange | Function | | Typescript:`(pageInfo: PageInfo, newDataSource: Array) => void`
trigger on pagination changing | N +onRowClick | Function | | Typescript:`(context: RowEventContext) => void`
trigger on row click。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface RowEventContext { row: T; index: number; e: MouseEvent }`
| N +onRowDblclick | Function | | Typescript:`(context: RowEventContext) => void`
trigger on double click | N +onRowMousedown | Function | | Typescript:`(context: RowEventContext) => void`
trigger on row mousedown | N +onRowMouseenter | Function | | Typescript:`(context: RowEventContext) => void`
trigger on row mouseenter | N +onRowMouseleave | Function | | Typescript:`(context: RowEventContext) => void`
trigger on row mouseenter | N +onRowMouseover | Function | | Typescript:`(context: RowEventContext) => void`
trigger on row mouseover | N +onRowMouseup | Function | | Typescript:`(context: RowEventContext) => void`
trigger on row mouseup | N +onScroll | Function | | Typescript:`(params: { e: WheelEvent }) => void`
trigger on table content scroll | N +onScrollX | Function | | Typescript:`(params: { e: WheelEvent }) => void`
`deprecated`。trigger on scroll horizontal | N +onScrollY | Function | | Typescript:`(params: { e: WheelEvent }) => void`
`deprecated`。trigger on scroll vertical | N ### BaseTable Events @@ -126,21 +126,21 @@ defaultSort | Object / Array | - | sort configs。uncontrolled property。Typesc sortIcon | Slot / Function | - | sort icon。Typescript:`TNode`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N sortOnRowDraggable | Boolean | false | `deprecated`。sort on row draggable | N `Omit, 'columns' | 'onCellClick'>` | \- | - | \- | N -onAsyncLoadingClick | Function | | TS 类型:`(context: { status: 'loading' | 'load-more' }) => void`
trigger on async loading text clicked | N -onCellClick | Function | | TS 类型:`(context: PrimaryTableCellEventContext) => void`
trigger on cell clicked。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface PrimaryTableCellEventContext { row: T; col: PrimaryTableCol; rowIndex: number; colIndex: number; e: MouseEvent }`
| N -onChange | Function | | TS 类型:`(data: TableChangeData, context: TableChangeContext) => void`
[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface TableChangeData { sorter?: TableSort; filter?: FilterValue; pagination?: PaginationProps }`

`interface TableChangeContext { trigger: TableChangeTrigger; currentData?: T[] }`

`type TableChangeTrigger = 'filter' | 'sorter' | 'pagination'`
| N -onColumnChange | Function | | TS 类型:`(context: PrimaryTableColumnChange) => void`
[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface PrimaryTableColumnChange { columns?: CheckboxGroupValue; currentColumn?: PrimaryTableCol; type?: 'check' | 'uncheck'; e?: Event }`
| N -onColumnControllerVisibleChange | Function | | TS 类型:`(visible: boolean, context: { trigger: 'cancel' | 'confirm' }) => void`
| N -onDataChange | Function | | TS 类型:`(data: Array, context: TableDataChangeContext) => void`
trigger on data changing。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface TableDataChangeContext { trigger: 'sort' }`
| N -onDisplayColumnsChange | Function | | TS 类型:`(value: CheckboxGroupValue) => void`
[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`import { CheckboxGroupValue } from '@Checkbox'`
| N -onDragSort | Function | | TS 类型:`(context: DragSortContext) => void`
trigger on drag sort。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface DragSortContext { currentIndex: number; current: T; targetIndex: number; target: T; data: T[]; newData: T[]; currentData?: T[]; e: SortableEvent; sort: 'row' | 'col' }`

`import { SortableEvent, SortableOptions } from 'sortablejs'`
| N -onExpandChange | Function | | TS 类型:`(expandedRowKeys: Array, options: ExpandOptions) => void`
trigger on expand row keys changing。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface ExpandOptions { expandedRowData: Array }`
| N -onFilterChange | Function | | TS 类型:`(filterValue: FilterValue, context: { col?: PrimaryTableCol }) => void`
trigger on filter value changing | N -onRowEdit | Function | | TS 类型:`(context: PrimaryTableRowEditContext) => void`
trigger on row data is editing。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`type PrimaryTableRowEditContext = PrimaryTableCellParams & { value: any }`
| N -onRowValidate | Function | | TS 类型:`(context: PrimaryTableRowValidateContext) => void`
trigger after row data validated。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`type PrimaryTableRowValidateContext = { result: TableRowValidateResult[]; trigger: TableValidateTrigger }`

`type TableValidateTrigger = 'self' | 'parent'`

`export type TableRowValidateResult = PrimaryTableCellParams & { errorList: AllValidateResult[]; value: any }`
| N -onSelectChange | Function | | TS 类型:`(selectedRowKeys: Array, options: SelectOptions) => void`
trigger on select changing。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface SelectOptions { selectedRowData: Array; type: 'uncheck' | 'check'; currentRowKey?: string; currentRowData?: T }`
| N -onSortChange | Function | | TS 类型:`(sort: TableSort, options: SortOptions) => void`
trigger on sort changing。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface SortOptions { currentDataSource?: Array; col: PrimaryTableCol }`
| N -onValidate | Function | | TS 类型:`(context: PrimaryTableValidateContext) => void`
trigger after row data validated。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface PrimaryTableValidateContext { result: TableErrorListMap }`

`type TableErrorListMap = { [key: string]: AllValidateResult[] }`
| N +onAsyncLoadingClick | Function | | Typescript:`(context: { status: 'loading' | 'load-more' }) => void`
trigger on async loading text clicked | N +onCellClick | Function | | Typescript:`(context: PrimaryTableCellEventContext) => void`
trigger on cell clicked。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface PrimaryTableCellEventContext { row: T; col: PrimaryTableCol; rowIndex: number; colIndex: number; e: MouseEvent }`
| N +onChange | Function | | Typescript:`(data: TableChangeData, context: TableChangeContext) => void`
[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface TableChangeData { sorter?: TableSort; filter?: FilterValue; pagination?: PaginationProps }`

`interface TableChangeContext { trigger: TableChangeTrigger; currentData?: T[] }`

`type TableChangeTrigger = 'filter' | 'sorter' | 'pagination'`
| N +onColumnChange | Function | | Typescript:`(context: PrimaryTableColumnChange) => void`
[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface PrimaryTableColumnChange { columns?: CheckboxGroupValue; currentColumn?: PrimaryTableCol; type?: 'check' | 'uncheck'; e?: Event }`
| N +onColumnControllerVisibleChange | Function | | Typescript:`(visible: boolean, context: { trigger: 'cancel' | 'confirm' }) => void`
| N +onDataChange | Function | | Typescript:`(data: Array, context: TableDataChangeContext) => void`
trigger on data changing。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface TableDataChangeContext { trigger: 'sort' }`
| N +onDisplayColumnsChange | Function | | Typescript:`(value: CheckboxGroupValue) => void`
[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`import { CheckboxGroupValue } from '@Checkbox'`
| N +onDragSort | Function | | Typescript:`(context: DragSortContext) => void`
trigger on drag sort。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface DragSortContext { currentIndex: number; current: T; targetIndex: number; target: T; data: T[]; newData: T[]; currentData?: T[]; e: SortableEvent; sort: 'row' | 'col' }`

`import { SortableEvent, SortableOptions } from 'sortablejs'`
| N +onExpandChange | Function | | Typescript:`(expandedRowKeys: Array, options: ExpandOptions) => void`
trigger on expand row keys changing。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface ExpandOptions { expandedRowData: Array }`
| N +onFilterChange | Function | | Typescript:`(filterValue: FilterValue, context: { col?: PrimaryTableCol }) => void`
trigger on filter value changing | N +onRowEdit | Function | | Typescript:`(context: PrimaryTableRowEditContext) => void`
trigger on row data is editing。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`type PrimaryTableRowEditContext = PrimaryTableCellParams & { value: any }`
| N +onRowValidate | Function | | Typescript:`(context: PrimaryTableRowValidateContext) => void`
trigger after row data validated。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`type PrimaryTableRowValidateContext = { result: TableRowValidateResult[]; trigger: TableValidateTrigger }`

`type TableValidateTrigger = 'self' | 'parent'`

`export type TableRowValidateResult = PrimaryTableCellParams & { errorList: AllValidateResult[]; value: any }`
| N +onSelectChange | Function | | Typescript:`(selectedRowKeys: Array, options: SelectOptions) => void`
trigger on select changing。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface SelectOptions { selectedRowData: Array; type: 'uncheck' | 'check'; currentRowKey?: string; currentRowData?: T }`
| N +onSortChange | Function | | Typescript:`(sort: TableSort, options: SortOptions) => void`
trigger on sort changing。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface SortOptions { currentDataSource?: Array; col: PrimaryTableCol }`
| N +onValidate | Function | | Typescript:`(context: PrimaryTableValidateContext) => void`
trigger after row data validated。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface PrimaryTableValidateContext { result: TableErrorListMap }`

`type TableErrorListMap = { [key: string]: AllValidateResult[] }`
| N ### PrimaryTable Events @@ -195,8 +195,8 @@ beforeDragSort | Function | - | stop to drag sort。Typescript:`(context: Drag tree | Object | - | tree data configs。Typescript:`TableTreeConfig` | N treeExpandAndFoldIcon | Function | - | sort icon。Typescript:`TNode<{ type: 'expand' | 'fold' }>`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N `PrimaryTableProps` | \- | - | \- | N -onAbnormalDragSort | Function | | TS 类型:`(context: TableAbnormalDragSortContext) => void`
[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface TableAbnormalDragSortContext { code: number; reason: string }`
| N -onTreeExpandChange | Function | | TS 类型:`(context: TableTreeExpandChangeContext) => void`
[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface TableTreeExpandChangeContext { row: T; rowIndex: number; rowState: TableRowState; trigger?: 'expand-fold-icon' }`
| N +onAbnormalDragSort | Function | | Typescript:`(context: TableAbnormalDragSortContext) => void`
[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface TableAbnormalDragSortContext { code: number; reason: string }`
| N +onTreeExpandChange | Function | | Typescript:`(context: TableTreeExpandChangeContext) => void`
[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts)。
`interface TableTreeExpandChangeContext { row: T; rowIndex: number; rowState: TableRowState; trigger?: 'expand-fold-icon' }`
| N ### EnhancedTable Events @@ -277,7 +277,7 @@ name | type | default | description | required abortEditOnEvent | Array | - | Typescript:`string[]` | N component | \- | - | component definition。Typescript:`ComponentType`。[see more ts definition](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N onEdited | Function | - | trigger on finishing editing。Typescript:`(context: { trigger: string; newRowData: T; rowIndex: number }) => void` | N -props | Object | - | props of `edit.component`。Typescript:`{ [key: string]: any }` | N +props | Object | - | props of `edit.component`。Typescript:`TableEditableCellProps` `type TableEditableCellProps = TablePlainObject | ((params: TableEditableCellPropsParams) => TablePlainObject)` `interface TableEditableCellPropsParams extends PrimaryTableCellParams { editedRow: T }` `interface TablePlainObject{ [key: string]: any }`。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts) | N rules | Array | - | form rules。Typescript:`FormRule[]`,[Form API Documents](./form?tab=api)。[see more ts definition](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts) | N showEditIcon | Boolean | true | show edit icon | N diff --git a/examples/table/table.md b/examples/table/table.md index 17a4ccf3a..7842bc0ed 100644 --- a/examples/table/table.md +++ b/examples/table/table.md @@ -8,7 +8,7 @@ allowResizeColumnWidth | Boolean | undefined | 已废弃。是否允许调整列宽。请更为使用 `resizable` | N bordered | Boolean | false | 是否显示表格边框 | N bottomContent | String / Slot / Function | - | 表格底部内容,可以用于自定义列设置等。TS 类型:`string | TNode`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N -cellEmptyContent | String / Slot / Function | '' | 单元格数据为空,呈现的内容。TS 类型:`string | TNode>`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N +cellEmptyContent | String / Slot / Function | - | 单元格数据为空时呈现的内容。TS 类型:`string | TNode>`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N columns | Array | [] | 列配置,泛型 T 指表格数据类型。TS 类型:`Array>` | N data | Array | [] | 数据源,泛型 T 指表格数据类型。TS 类型:`Array` | N disableDataPage | Boolean | false | 是否禁用本地数据分页。当 `data` 数据长度超过分页大小时,会自动进行本地数据分页。如果 `disableDataPage` 设置为 true,则无论何时,都不会进行本地数据分页 | N @@ -277,7 +277,7 @@ placement | String | top-right | 列配置按钮基于表格的放置位置: abortEditOnEvent | Array | - | 除了点击非自身元素退出编辑态之外,还有哪些事件退出编辑态。示例:`abortEditOnEvent: ['onChange']`。TS 类型:`string[]` | N component | \- | - | 组件定义,如:`Input` `Select`。对于完全自定义的组件(非组件库内的组件),组件需要支持 `value` 和 `onChange` ;如果还需要支持校验规则,则组件还需实现 `tips` 和 `status` 两个 API,实现规则可参考 `Input` 组件。TS 类型:`ComponentType`。[通用类型定义](https://github.com/Tencent/tdesign-vue/blob/develop/src/common.ts) | N onEdited | Function | - | 编辑完成后,退出编辑模式时触发。TS 类型:`(context: { trigger: string; newRowData: T; rowIndex: number }) => void` | N -props | Object | - | 透传给组件 `edit.component` 的属性。TS 类型:`{ [key: string]: any }` | N +props | Object | - | 透传给组件 `edit.component` 的属性。TS 类型:`TableEditableCellProps` `type TableEditableCellProps = TablePlainObject | ((params: TableEditableCellPropsParams) => TablePlainObject)` `interface TableEditableCellPropsParams extends PrimaryTableCellParams { editedRow: T }` `interface TablePlainObject{ [key: string]: any }`。[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts) | N rules | Array | - | 校验规则。TS 类型:`FormRule[]`,[Form API Documents](./form?tab=api)。[详细类型定义](https://github.com/Tencent/tdesign-vue/tree/develop/src/table/type.ts) | N showEditIcon | Boolean | true | 是否显示编辑图标 | N diff --git a/src/table/base-table-props.ts b/src/table/base-table-props.ts index 2141a8ed6..c84bedf84 100644 --- a/src/table/base-table-props.ts +++ b/src/table/base-table-props.ts @@ -19,10 +19,9 @@ export default { bottomContent: { type: [String, Function] as PropType, }, - /** 单元格数据为空,呈现的内容 */ + /** 单元格数据为空时呈现的内容 */ cellEmptyContent: { type: [String, Function] as PropType, - default: '', }, /** 列配置,泛型 T 指表格数据类型 */ columns: { diff --git a/src/table/editable-cell.tsx b/src/table/editable-cell.tsx index 4ef92e561..337342fb7 100644 --- a/src/table/editable-cell.tsx +++ b/src/table/editable-cell.tsx @@ -226,6 +226,14 @@ export default defineComponent({ if (!isEdit.value) return; // @ts-ignore if (e.path?.includes(tableEditableCellRef.value?.$el)) return; + // @ts-ignore 如果点击到 Popup 复层也直接返回 + for (let i = 0, len = e.path.length; i < len; i++) { + // @ts-ignore + const node = e.path[i]; + if (node.classList?.value?.includes('popup__content')) { + return; + } + } const outsideAbortEvent = col.value.edit.onEdited; updateAndSaveAbort(outsideAbortEvent, { trigger: 'document', diff --git a/src/table/hooks/useEditableRow.ts b/src/table/hooks/useEditableRow.ts index 7adc17b63..234eadc3e 100644 --- a/src/table/hooks/useEditableRow.ts +++ b/src/table/hooks/useEditableRow.ts @@ -8,16 +8,35 @@ import { PrimaryTableRowEditContext, PrimaryTableRowValidateContext, TableRowData, TableErrorListMap, } from '../type'; -const cellRuleMap = new Map[]>(); - export type ErrorListObjectType = PrimaryTableRowEditContext & { errorList: AllValidateResult[] }; +export interface TablePromiseErrorData { + errors: ErrorListObjectType[]; + errorMap: TableErrorListMap; +} + +const cellRuleMap = new Map[]>(); + export default function useRowEdit(props: PrimaryTableProps, context: SetupContext) { // 校验不通过的错误信息,其中 key 值为 [rowValue, col.colKey].join('__') const errorListMap = ref({}); // 处于编辑态的表格行 const editableKeysMap = computed(() => getEditableKeysMap(props.editableRowKeys, props.data, props.rowKey || 'id')); + const getErrorListMapByErrors = (errors: ErrorListObjectType[]): TableErrorListMap => { + const errorMap: TableErrorListMap = {}; + errors.forEach(({ row, col, errorList }) => { + const rowValue = get(row, props.rowKey || 'id'); + const key = [rowValue, col.colKey].join('__'); + if (errorList?.length) { + errorMap[key] = errorList; + } else { + delete errorMap[key]; + } + }); + return errorMap; + }; + // 校验一行的数据 const validateOneRowData = (rowValue: any) => { const rowRules = cellRuleMap.get(rowValue); @@ -34,25 +53,11 @@ export default function useRowEdit(props: PrimaryTableProps, context: SetupConte }); }), ); - return new Promise<{ - errors: ErrorListObjectType[]; - errorMap: TableErrorListMap; - }>((resolve, reject) => { + return new Promise((resolve, reject) => { Promise.all(list).then((errors) => { - const errorMap: TableErrorListMap = { ...errorListMap.value }; - errors.forEach(({ row, col, errorList }) => { - const rowValue = get(row, props.rowKey || 'id'); - const key = [rowValue, col.colKey].join('__'); - if (errorList?.length) { - errorMap[key] = errorList; - } else { - delete errorMap[key]; - } - }); - errorListMap.value = errorMap; resolve({ errors: errors.filter((t) => t.errorList?.length), - errorMap, + errorMap: getErrorListMapByErrors(errors), }); }, reject); }); @@ -62,28 +67,36 @@ export default function useRowEdit(props: PrimaryTableProps, context: SetupConte * 校验表格单行数据(对外开放方法,修改时需慎重) * @param rowValue 行唯一标识 */ - const validateRowData = (rowValue: any) => { - validateOneRowData(rowValue).then(({ errors }) => { + const validateRowData = (rowValue: any) => new Promise((resolve, reject) => { + validateOneRowData(rowValue).then(({ errors, errorMap }) => { + errorListMap.value = errorMap; // 缺少校验文本显示 const tTrigger = 'parent'; props.onRowValidate?.({ trigger: tTrigger, result: errors }); - context.emit('row-validate', { trigger: tTrigger, result: errors }); - }); - }; + resolve({ trigger: tTrigger, result: errors }); + }, reject); + }); /** * 校验整个表格数据(对外开放方法,修改时需慎重) */ const validateTableData = () => { - const promiseList = []; + const promiseList: Promise[] = []; const data = props.data || []; for (let i = 0, len = data.length; i < len; i++) { const rowValue = get(data[i], props.rowKey || 'id'); promiseList.push(validateOneRowData(rowValue)); } - Promise.all(promiseList).then(() => { - props.onValidate?.({ result: errorListMap.value }); - context.emit('validate', { result: errorListMap.value }); + return new Promise((resolve, reject) => { + Promise.all(promiseList).then((rList) => { + const allErrorListMap: TableErrorListMap = {}; + rList.forEach(({ errorMap } = { errors: [], errorMap: {} }) => { + errorMap && Object.assign(allErrorListMap, errorMap); + }); + errorListMap.value = allErrorListMap; + props.onValidate?.({ result: allErrorListMap }); + resolve({ result: allErrorListMap }); + }, reject); }); }; diff --git a/src/table/type.ts b/src/table/type.ts index f5e3cf297..3850c9586 100644 --- a/src/table/type.ts +++ b/src/table/type.ts @@ -35,8 +35,7 @@ export interface TdBaseTableProps { */ bottomContent?: string | TNode; /** - * 单元格数据为空,呈现的内容 - * @default '' + * 单元格数据为空时呈现的内容 */ cellEmptyContent?: string | TNode>; /** @@ -789,7 +788,7 @@ export interface TableEditableCellConfig /** * 透传给组件 `edit.component` 的属性 */ - props?: { [key: string]: any }; + props?: TableEditableCellProps; /** * 校验规则 */ @@ -1033,3 +1032,15 @@ export interface SwapParams { export type FilterProps = RadioProps | CheckboxProps | InputProps | { [key: string]: any }; export type FilterType = 'input' | 'single' | 'multiple'; + +export type TableEditableCellProps = + | TablePlainObject + | ((params: TableEditableCellPropsParams) => TablePlainObject); + +export interface TableEditableCellPropsParams extends PrimaryTableCellParams { + editedRow: T; +} + +export interface TablePlainObject { + [key: string]: any; +}