Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Table] fix column resize problem; column controller of multiple header improvement #2916

Merged
merged 6 commits into from
Nov 22, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -159,13 +159,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 @@ -231,7 +234,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
Loading