From 239cb22d38f45a8e6f2ef0170ba7f451eea38044 Mon Sep 17 00:00:00 2001 From: lxp Date: Mon, 18 Sep 2023 11:06:03 +0800 Subject: [PATCH 1/3] above body footer --- examples/views/grid/Footer.vue | 1 + examples/views/table/advanced/Footer.vue | 1 + packages/table/src/props.ts | 2 + packages/table/src/table.ts | 59 +++++++++++++++++------- styles/table.scss | 13 ++++-- types/table.d.ts | 5 ++ 6 files changed, 61 insertions(+), 20 deletions(-) diff --git a/examples/views/grid/Footer.vue b/examples/views/grid/Footer.vue index c4533d68df..1129138b91 100644 --- a/examples/views/grid/Footer.vue +++ b/examples/views/grid/Footer.vue @@ -41,6 +41,7 @@ export default defineComponent({ const gridOptions = reactive({ border: true, stripe: true, + aboveBodyFooter: true, resizable: true, showFooter: true, height: 400, diff --git a/examples/views/table/advanced/Footer.vue b/examples/views/table/advanced/Footer.vue index 942f102a80..8c8c5d38fb 100644 --- a/examples/views/table/advanced/Footer.vue +++ b/examples/views/table/advanced/Footer.vue @@ -67,6 +67,7 @@ show-overflow class="mytable-footer" height="400" + above-body-footer :show-header="demo3.showHeader" :show-footer="demo3.showFooter" :footer-method="footerMethod" diff --git a/packages/table/src/props.ts b/packages/table/src/props.ts index 81e643c288..d1985702fe 100644 --- a/packages/table/src/props.ts +++ b/packages/table/src/props.ts @@ -48,6 +48,8 @@ export default { highlightCell: Boolean as PropType, // 是否显示表尾合计 showFooter: Boolean as PropType, + // 表尾放到 body 上方 + aboveBodyFooter: Boolean as PropType, // 表尾合计的计算方法 footerMethod: Function as PropType, // 给行附加 className diff --git a/packages/table/src/table.ts b/packages/table/src/table.ts index b259e177c7..ea404c5199 100644 --- a/packages/table/src/table.ts +++ b/packages/table/src/table.ts @@ -1455,7 +1455,7 @@ export default defineComponent({ } const updateStyle = () => { - const { border, showFooter, showOverflow: allColumnOverflow, showHeaderOverflow: allColumnHeaderOverflow, showFooterOverflow: allColumnFooterOverflow, mouseConfig, spanMethod, footerSpanMethod, keyboardConfig } = props + const { border, showFooter, aboveBodyFooter, showOverflow: allColumnOverflow, showHeaderOverflow: allColumnHeaderOverflow, showFooterOverflow: allColumnFooterOverflow, mouseConfig, spanMethod, footerSpanMethod, keyboardConfig } = props const { isGroup, currentRow, tableColumn, scrollXLoad, scrollYLoad, scrollbarWidth, scrollbarHeight, columnStore, editStore, mergeList, mergeFooterList, isAllOverflow } = reactData let { visibleColumn, fullColumnIdData, tableHeight, tableWidth, headerHeight, footerHeight, elemStore, customHeight, customMinHeight, customMaxHeight } = internalData const containerList = ['main', 'left', 'right'] @@ -1466,11 +1466,12 @@ export default defineComponent({ const bodyWrapperRef = elemStore['main-body-wrapper'] const bodyWrapperElem = bodyWrapperRef ? bodyWrapperRef.value : null if (emptyPlaceholderElem) { - emptyPlaceholderElem.style.top = `${headerHeight}px` + // emptyPlaceholderElem.style.top = `${headerHeight}px` + emptyPlaceholderElem.style.top = `${headerHeight + ((showFooter && aboveBodyFooter) ? footerHeight : 0)}px` emptyPlaceholderElem.style.height = bodyWrapperElem ? `${bodyWrapperElem.offsetHeight - scrollbarHeight}px` : '' } if (customHeight > 0) { - if (showFooter) { + if (showFooter && aboveBodyFooter) { customHeight += scrollbarHeight } } @@ -1549,14 +1550,14 @@ export default defineComponent({ const emptyBlockRef = elemStore[`${name}-${layout}-emptyBlock`] const emptyBlockElem = emptyBlockRef ? emptyBlockRef.value : null if (isNodeElement(wrapperElem)) { - const bodyMinHeight = fixedType ? ((customMinHeight - headerHeight - footerHeight) - (showFooter ? 0 : scrollbarHeight)) : (customMinHeight - headerHeight - footerHeight) + const bodyMinHeight = fixedType ? ((customMinHeight - headerHeight - footerHeight) - (showFooter && !aboveBodyFooter ? 0 : scrollbarHeight)) : (customMinHeight - headerHeight - footerHeight) let bodyMaxHeight = 0 if (customMaxHeight) { - bodyMaxHeight = Math.max(bodyMinHeight, fixedType ? (customMaxHeight - headerHeight - (showFooter ? 0 : scrollbarHeight)) : (customMaxHeight - headerHeight - footerHeight)) + bodyMaxHeight = Math.max(bodyMinHeight, fixedType ? (customMaxHeight - headerHeight - (showFooter && !aboveBodyFooter ? 0 : scrollbarHeight)) : (customMaxHeight - headerHeight - footerHeight)) wrapperElem.style.maxHeight = `${bodyMaxHeight}px` } if (customHeight > 0) { - let bodyHeight = fixedType ? ((customHeight > 0 ? customHeight - headerHeight - footerHeight : tableHeight) - (showFooter ? 0 : scrollbarHeight)) : (customHeight - headerHeight - footerHeight) + let bodyHeight = fixedType ? ((customHeight > 0 ? customHeight - headerHeight - footerHeight : tableHeight) - (showFooter && !aboveBodyFooter ? 0 : scrollbarHeight)) : (customHeight - headerHeight - footerHeight) if (bodyMaxHeight) { bodyHeight = Math.min(bodyMaxHeight, bodyHeight) } @@ -1569,10 +1570,14 @@ export default defineComponent({ // 如果是固定列 if (fixedWrapperElem) { + let fixedHeight = 0 if (isNodeElement(wrapperElem)) { - wrapperElem.style.top = `${headerHeight}px` + if (showFooter && aboveBodyFooter) { + fixedHeight = Math.max(wrapperElem.offsetHeight - wrapperElem.clientHeight - (scrollbarHeight * 2), 0) + } + wrapperElem.style.top = aboveBodyFooter ? `${(customHeight > 0 ? customHeight - footerHeight : tableHeight + headerHeight) - fixedHeight}px` : `${headerHeight}px` } - fixedWrapperElem.style.height = `${(customHeight > 0 ? customHeight - headerHeight - footerHeight : tableHeight) + headerHeight + footerHeight - scrollbarHeight * (showFooter ? 2 : 1)}px` + fixedWrapperElem.style.height = `${((customHeight > 0 ? customHeight - headerHeight - footerHeight : tableHeight) + headerHeight + footerHeight - scrollbarHeight * (showFooter ? 2 : 1)) - fixedHeight}px` fixedWrapperElem.style.width = `${fixedColumn.reduce((previous, column) => previous + column.renderWidth, isFixedLeft ? 0 : scrollbarWidth)}px` } @@ -1624,7 +1629,7 @@ export default defineComponent({ if (isNodeElement(wrapperElem)) { // 如果是固定列 if (fixedWrapperElem) { - wrapperElem.style.top = `${customHeight > 0 ? customHeight - footerHeight : tableHeight + headerHeight}px` + wrapperElem.style.top = aboveBodyFooter ? `${headerHeight}px` : `${customHeight > 0 ? customHeight - footerHeight : tableHeight + headerHeight}px` } wrapperElem.style.marginTop = `${-Math.max(1, scrollbarHeight)}px` } @@ -6092,7 +6097,7 @@ export default defineComponent({ * @param {String} fixedType 固定列类型 */ const renderFixed = (fixedType: 'left' | 'right') => { - const { showHeader, showFooter } = props + const { showHeader, showFooter, aboveBodyFooter } = props const { tableData, tableColumn, tableGroupColumn, columnStore, footerTableData } = reactData const isFixedLeft = fixedType === 'left' const fixedColumn = isFixedLeft ? columnStore.leftList : columnStore.rightList @@ -6108,6 +6113,15 @@ export default defineComponent({ tableGroupColumn, fixedColumn }) : createCommentVNode(), + + aboveBodyFooter ? (showFooter ? h(TableFooterComponent, { + ref: isFixedLeft ? refTableLeftFooter : refTableRightFooter, + footerTableData, + tableColumn, + fixedColumn, + fixedType + }) : createCommentVNode()) : createCommentVNode(), + h(TableBodyComponent as ComponentOptions, { ref: isFixedLeft ? refTableLeftBody : refTableRightBody, fixedType, @@ -6115,17 +6129,17 @@ export default defineComponent({ tableColumn, fixedColumn }), - showFooter ? h(TableFooterComponent, { + showFooter ? (!aboveBodyFooter ? h(TableFooterComponent, { ref: isFixedLeft ? refTableLeftFooter : refTableRightFooter, footerTableData, tableColumn, fixedColumn, fixedType - }) : createCommentVNode() + }) : createCommentVNode()) : createCommentVNode() ]) } - const renderEmptyContenet = () => { + const renderEmptyContent = () => { const emptyOpts = computeEmptyOpts.value const params = { $table: $xetable } if (slots.empty) { @@ -6512,7 +6526,7 @@ export default defineComponent({ }) const renderVN = () => { - const { loading, stripe, showHeader, height, treeConfig, mouseConfig, showFooter, highlightCell, highlightHoverRow, highlightHoverColumn, editConfig, editRules } = props + const { loading, stripe, showHeader, height, treeConfig, mouseConfig, showFooter, aboveBodyFooter, highlightCell, highlightHoverRow, highlightHoverColumn, editConfig, editRules } = props const { isGroup, overflowX, overflowY, scrollXLoad, scrollYLoad, scrollbarHeight, tableData, tableColumn, tableGroupColumn, footerTableData, initStore, columnStore, filterStore } = reactData const { leftList, rightList } = columnStore const loadingSlot = slots.loading @@ -6541,6 +6555,7 @@ export default defineComponent({ 'column--highlight': columnOpts.isHover || highlightHoverColumn, 'is--header': showHeader, 'is--footer': showFooter, + 'is--above-body-footer': aboveBodyFooter, 'is--group': isGroup, 'is--tree-line': treeConfig && (treeOpts.showLine || treeOpts.line), 'is--fixed-left': leftList.length, @@ -6578,6 +6593,16 @@ export default defineComponent({ tableColumn, tableGroupColumn }) : createCommentVNode(), + + /** + * 表尾 + */ + aboveBodyFooter ? (showFooter ? h(TableFooterComponent, { + ref: refTableFooter, + footerTableData, + tableColumn + }) : createCommentVNode()) : createCommentVNode(), + /** * 表体 */ @@ -6589,11 +6614,11 @@ export default defineComponent({ /** * 表尾 */ - showFooter ? h(TableFooterComponent, { + showFooter ? (!aboveBodyFooter ? h(TableFooterComponent, { ref: refTableFooter, footerTableData, tableColumn - }) : createCommentVNode() + }) : createCommentVNode()) : createCommentVNode() ]), h('div', { class: 'vxe-table--fixed-wrapper' @@ -6617,7 +6642,7 @@ export default defineComponent({ }, [ h('div', { class: 'vxe-table--empty-content' - }, renderEmptyContenet()) + }, renderEmptyContent()) ]), /** * 边框线 diff --git a/styles/table.scss b/styles/table.scss index da7ee03261..768e24857e 100644 --- a/styles/table.scss +++ b/styles/table.scss @@ -658,7 +658,7 @@ user-select: none; } } - + /*边框*/ .vxe-table--footer-wrapper { border-top: var(--vxe-table-border-width) solid var(--vxe-table-border-color); @@ -736,7 +736,7 @@ display: none; } } - + &.size--medium { font-size: var(--vxe-font-size-medium); .vxe-table--empty-placeholder, @@ -1352,6 +1352,13 @@ } } } + + /*above body footer*/ + &.is--above-body-footer { + .vxe-table--footer-wrapper.body--wrapper { + overflow: hidden; + } + } } /*valid error*/ @@ -1389,4 +1396,4 @@ div.vxe-table--tooltip-wrapper { } } } -} \ No newline at end of file +} diff --git a/types/table.d.ts b/types/table.d.ts index 81cbfd2b2a..08c5663595 100644 --- a/types/table.d.ts +++ b/types/table.d.ts @@ -1151,6 +1151,7 @@ export namespace VxeTablePropTypes { export type HighlightHoverColumn = boolean export type HighlightCell = boolean export type ShowFooter = boolean + export type AboveBodyFooter = boolean; export type FooterMethod = (params: { $table: VxeTableConstructor & VxeTablePrivateMethods @@ -2425,6 +2426,10 @@ export type VxeTableProps = { * 是否显示表尾 */ showFooter?: VxeTablePropTypes.ShowFooter + /** + * 表尾放在body上方 + */ + aboveBodyFooter?: VxeTablePropTypes.AboveBodyFooter /** * 表尾的数据获取方法,返回一个二维数组 */ From f7e1b943a32385fb3d11e80904d648120d352b3f Mon Sep 17 00:00:00 2001 From: lxp Date: Mon, 18 Sep 2023 11:13:48 +0800 Subject: [PATCH 2/3] =?UTF-8?q?=E5=BA=94=E8=AF=A5=E5=8F=96=E5=8F=8D?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/table/src/table.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/table/src/table.ts b/packages/table/src/table.ts index ea404c5199..ddd252f4b6 100644 --- a/packages/table/src/table.ts +++ b/packages/table/src/table.ts @@ -1471,7 +1471,7 @@ export default defineComponent({ emptyPlaceholderElem.style.height = bodyWrapperElem ? `${bodyWrapperElem.offsetHeight - scrollbarHeight}px` : '' } if (customHeight > 0) { - if (showFooter && aboveBodyFooter) { + if (showFooter && !aboveBodyFooter) { customHeight += scrollbarHeight } } From fb037b928d169d5f8c0eb99d299c9623e34c113d Mon Sep 17 00:00:00 2001 From: lxp Date: Mon, 18 Sep 2023 12:18:09 +0800 Subject: [PATCH 3/3] =?UTF-8?q?=E8=B0=83=E6=95=B4=E8=AE=A1=E7=AE=97?= =?UTF-8?q?=E7=9A=84=E9=80=BB=E8=BE=91?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- packages/table/src/table.ts | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/table/src/table.ts b/packages/table/src/table.ts index ddd252f4b6..7441a98ddc 100644 --- a/packages/table/src/table.ts +++ b/packages/table/src/table.ts @@ -1550,14 +1550,14 @@ export default defineComponent({ const emptyBlockRef = elemStore[`${name}-${layout}-emptyBlock`] const emptyBlockElem = emptyBlockRef ? emptyBlockRef.value : null if (isNodeElement(wrapperElem)) { - const bodyMinHeight = fixedType ? ((customMinHeight - headerHeight - footerHeight) - (showFooter && !aboveBodyFooter ? 0 : scrollbarHeight)) : (customMinHeight - headerHeight - footerHeight) + const bodyMinHeight = fixedType ? ((customMinHeight - headerHeight - footerHeight) - (showFooter ? 0 : scrollbarHeight)) : (customMinHeight - headerHeight - footerHeight) let bodyMaxHeight = 0 if (customMaxHeight) { - bodyMaxHeight = Math.max(bodyMinHeight, fixedType ? (customMaxHeight - headerHeight - (showFooter && !aboveBodyFooter ? 0 : scrollbarHeight)) : (customMaxHeight - headerHeight - footerHeight)) + bodyMaxHeight = Math.max(bodyMinHeight, fixedType ? (customMaxHeight - headerHeight - (showFooter ? 0 : scrollbarHeight)) : (customMaxHeight - headerHeight - footerHeight)) wrapperElem.style.maxHeight = `${bodyMaxHeight}px` } if (customHeight > 0) { - let bodyHeight = fixedType ? ((customHeight > 0 ? customHeight - headerHeight - footerHeight : tableHeight) - (showFooter && !aboveBodyFooter ? 0 : scrollbarHeight)) : (customHeight - headerHeight - footerHeight) + let bodyHeight = fixedType ? ((customHeight > 0 ? customHeight - headerHeight - footerHeight : tableHeight) - (showFooter ? 0 : scrollbarHeight)) : (customHeight - headerHeight - footerHeight) if (bodyMaxHeight) { bodyHeight = Math.min(bodyMaxHeight, bodyHeight) } @@ -1573,11 +1573,11 @@ export default defineComponent({ let fixedHeight = 0 if (isNodeElement(wrapperElem)) { if (showFooter && aboveBodyFooter) { - fixedHeight = Math.max(wrapperElem.offsetHeight - wrapperElem.clientHeight - (scrollbarHeight * 2), 0) + fixedHeight = Math.max(wrapperElem.offsetHeight - wrapperElem.clientHeight - scrollbarHeight, 0) } - wrapperElem.style.top = aboveBodyFooter ? `${(customHeight > 0 ? customHeight - footerHeight : tableHeight + headerHeight) - fixedHeight}px` : `${headerHeight}px` + wrapperElem.style.top = showFooter && aboveBodyFooter ? `${(customHeight > 0 ? customHeight - footerHeight + scrollbarHeight - fixedHeight : headerHeight + footerHeight - scrollbarHeight * 2)}px` : `${headerHeight}px` } - fixedWrapperElem.style.height = `${((customHeight > 0 ? customHeight - headerHeight - footerHeight : tableHeight) + headerHeight + footerHeight - scrollbarHeight * (showFooter ? 2 : 1)) - fixedHeight}px` + fixedWrapperElem.style.height = `${(customHeight > 0 ? customHeight - headerHeight - footerHeight : tableHeight) + headerHeight + footerHeight - scrollbarHeight * (showFooter ? 2 : 1) - fixedHeight}px` fixedWrapperElem.style.width = `${fixedColumn.reduce((previous, column) => previous + column.renderWidth, isFixedLeft ? 0 : scrollbarWidth)}px` }