Skip to content

Commit

Permalink
[Table] fix column resize problem; column controller of multiple head…
Browse files Browse the repository at this point in the history
…er improvement (Tencent#2916)

* docs: demo inprovement

* fix(table): multi header column config

* fix: 修复列宽调整问题

* fix(table): column controller of multiple header does not work

* test: update snapshots

* test: update snapshots
  • Loading branch information
chaishi authored Nov 22, 2023
1 parent 168f103 commit 65ed909
Show file tree
Hide file tree
Showing 8 changed files with 336 additions and 279 deletions.
79 changes: 44 additions & 35 deletions src/table/_example/affix.vue
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
<template>
<!-- 注意组件父元素的宽度 -->
<div class="tdesign-demo-block-column-large tdesign-demo__table tdesign-demo__table-affix" style="width: 830px">
<div>
<t-space>
<t-checkbox v-model="headerAffixedTop">表头吸顶</t-checkbox>
<t-checkbox v-model="footerAffixedBottom" style="margin-left: 32px">表尾吸底</t-checkbox>
<t-checkbox v-model="horizontalScrollAffixedBottom" style="margin-left: 32px">滚动条吸底</t-checkbox>
<t-checkbox v-model="paginationAffixedBottom" style="margin-left: 32px">分页器吸底</t-checkbox>
<t-checkbox v-model="fixedLeftColumn" style="margin-left: 32px">固定左侧列</t-checkbox>
<t-checkbox v-model="fixedRightColumn" style="margin-left: 32px">固定右侧列</t-checkbox>
</div>
<t-checkbox v-model="footerAffixedBottom">表尾吸底</t-checkbox>
<t-checkbox v-model="horizontalScrollAffixedBottom">滚动条吸底</t-checkbox>
<t-checkbox v-model="paginationAffixedBottom">分页器吸底</t-checkbox>
<t-checkbox v-model="fixedLeftColumn">固定左侧列</t-checkbox>
<t-checkbox v-model="fixedRightColumn">固定右侧列</t-checkbox>
</t-space>
<t-table
rowKey="index"
:data="data"
:columns="columns"
:footData="footData"
:rowClassName="rowClassName"
:pagination="pagination"
:headerAffixedTop="headerAffixedTop ? headerAffixedTopProps : undefined"
:footerAffixedBottom="footerAffixedBottom ? footerAffixedBottomProps : false"
:horizontalScrollAffixedBottom="horizontalScrollAffixedBottom ? horizontalScrollAffixedBottomProps : false"
:header-affixed-top="headerAffixedTopProps"
:footer-affixed-bottom="footerAffixedBottomProps"
:horizontal-scroll-affixed-bottom="horizontalScrollAffixedBottomProps"
:paginationAffixedBottom="paginationAffixedBottom"
table-layout="fixed"
dragSort="col"
Expand Down Expand Up @@ -109,43 +109,52 @@ export default {
TOTAL,
// 重要:如果在预渲染场景下,初次渲染的表格宽度和最终呈现宽度不一样,请异步设置表头吸顶
headerAffixedTop: true,
footerAffixedBottom: true,
footerAffixedBottom: false,
fixedLeftColumn: true,
fixedRightColumn: true,
horizontalScrollAffixedBottom: false,
paginationAffixedBottom: false,
horizontalScrollAffixedBottom: true,
paginationAffixedBottom: true,
// 表尾有一行数据
footData: [{ index: 'footer-row-1', type: '全部类型', description: '-' }],
columns: [],
pagination: { defaultCurrent: 1, defaultPageSize: 5, total: TOTAL },
headerAffixedTopProps: {
offsetTop: 87,
zIndex: 1000,
},
footerAffixedBottomProps: {
offsetBottom: this.paginationAffixedBottom ? 60 : 0,
zIndex: 1000,
},
horizontalScrollAffixedBottomProps: {
offsetBottom: this.paginationAffixedBottom ? 61 : 0,
zIndex: 1000,
},
};
},
watch: {
paginationAffixedBottom(val) {
this.footerAffixedBottomProps.offsetBottom = val ? 60 : 0;
this.horizontalScrollAffixedBottomProps.offsetBottom = val ? 61 : 0;
computed: {
headerAffixedTopProps() {
if (this.headerAffixedTop) {
return {
offsetTop: 87,
zIndex: 1000,
// container used to set scroll container, default container is body
// container: () => document.body,
};
}
return false;
},
// 底部滚动条 和 Footer 无需同时出现,二选一即可
horizontalScrollAffixedBottom(val) {
val && (this.footerAffixedBottom = false);
footerAffixedBottomProps() {
if (this.footerAffixedBottom) {
return {
offsetBottom: this.paginationAffixedBottom ? 64 : 0,
zIndex: 1000,
};
}
return false;
},
// 底部滚动条 和 Footer 无需同时出现,二选一即可
footerAffixedBottom(val) {
val && (this.horizontalScrollAffixedBottom = false);
horizontalScrollAffixedBottomProps() {
if (this.horizontalScrollAffixedBottom) {
return {
// height of pagination component is 64
offsetBottom: this.paginationAffixedBottom ? 64 : 0,
zIndex: 1000,
};
}
return false;
},
},
watch: {
// 左侧固定列发生变化时
fixedLeftColumn: {
handler(val) {
Expand Down
2 changes: 1 addition & 1 deletion src/table/_example/multi-header.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@

<!-- tableContentWidth 必须大于表格的外层宽度,否则请设置 width: 100% -->
<!-- 多级表头中,如果要使用固定列功能,则必须设置 colKey 和 fixed -->
<!-- :scroll="{ type: 'virtual' }" 表示虚拟滚动 -->
<!-- :scroll="{ type: 'virtual' }" virtual scroll for a lot of data rendered-->
<t-table
row-key="index"
:data="data"
Expand Down
1 change: 1 addition & 0 deletions src/table/hooks/useAffix.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ export default function useAffix(props: TdBaseTableProps) {
const updateAffixHeaderOrFooter = () => {
if (!isAffixed.value && !isVirtualScroll.value) return;
const pos = tableContentRef.value?.getBoundingClientRect();
if (!pos) return;
const headerRect = tableContentRef.value?.querySelector('thead')?.getBoundingClientRect();
const headerHeight = headerRect?.height || 0;
const footerRect = affixFooterRef.value?.getBoundingClientRect();
Expand Down
8 changes: 4 additions & 4 deletions src/table/hooks/useColumnController.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ interface CheckboxGroupOptionsType {
export function getColumnKeys(columns: PrimaryTableCol[], keys = new Set<string>()) {
for (let i = 0, len = columns.length; i < len; i++) {
const col = columns[i];
col.colKey && keys.add(col.colKey);
if (col.children?.length) {
getColumnKeys(col.children, keys);
} else {
col.colKey && keys.add(col.colKey);
}
}
return keys;
Expand Down Expand Up @@ -123,11 +124,10 @@ export default function useColumnController(props: TdPrimaryTableProps, context:
// 减少循环次数
for (let i = 0, len = columns.length; i < len; i++) {
const item = columns[i];
if (item.colKey) {
arr.push(getOneColumnItem(item, i));
}
if (item.children?.length) {
getCheckboxOptions(item.children, arr);
} else if (item.colKey) {
arr.push(getOneColumnItem(item, i));
}
}
return arr;
Expand Down
9 changes: 7 additions & 2 deletions src/table/hooks/useFixed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
import get from 'lodash/get';
import xorWith from 'lodash/xorWith';
import debounce from 'lodash/debounce';
import pick from 'lodash/pick';
import log from '../../_common/js/log';
import { ClassName, Styles } from '../../common';
import { BaseTableCol, TableRowData, TdBaseTableProps } from '../type';
Expand Down Expand Up @@ -512,8 +513,12 @@ export default function useFixed(
reduceKeys.forEach((key) => {
reduceWidth += thWidthList[key];
});
const oldTotalWidth = Object.values(thWidthList).reduce((r = 0, n) => r + n);
setTableElmWidth(oldTotalWidth - reduceWidth);
const rootThWidthList = pick(thWidthList, preColKeys);
const oldTotalWidth = Object.values(rootThWidthList).reduce((r = 0, n) => r + n);
// 保留原有可能编辑过的列宽度,但是当剩余列过小时,表头小于内容宽,需要缩放回内容宽度
const contentWidth = tableContentRef.value.clientWidth;
const widthToReserve = oldTotalWidth - reduceWidth;
setTableElmWidth(Math.max(contentWidth, widthToReserve));
}
});

Expand Down
9 changes: 6 additions & 3 deletions src/table/primary-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,16 @@ export default defineComponent({
};

// 1. 影响列数量的因素有:自定义列配置、展开/收起行、多级表头;2. 影响表头内容的因素有:排序图标、筛选图标
const getColumns = (columns: PrimaryTableCol<TableRowData>[]) => {
const getColumns = (columns: PrimaryTableCol<TableRowData>[], parentDisplay = false) => {
const arr: PrimaryTableCol<TableRowData>[] = [];
for (let i = 0, len = columns.length; i < len; i++) {
let item = { ...columns[i] };
// 自定义列显示控制
const isDisplayColumn = item.children?.length || tDisplayColumns.value?.includes(item.colKey);
if (!isDisplayColumn && props.columnController) continue;
const isColumnController = Boolean(
props.columnController || props.displayColumns || props.defaultDisplayColumns,
);
if (!isDisplayColumn && isColumnController && !parentDisplay) continue;
item = formatToRowSelectColumn(item);
const { sort } = props;
if (item.sorter && props.showSortColumnBgColor) {
Expand Down Expand Up @@ -245,7 +248,7 @@ export default defineComponent({
};
}
if (item.children?.length) {
item.children = getColumns(item.children);
item.children = getColumns(item.children, parentDisplay || tDisplayColumns.value?.includes(item.colKey));
}
// 多级表头和自定义列配置特殊逻辑:要么子节点不存在,要么子节点长度大于 1,方便做自定义列配置
if (!item.children || item.children?.length) {
Expand Down
Loading

0 comments on commit 65ed909

Please sign in to comment.