Skip to content

Commit 38569c2

Browse files
committed
perf: table use sticky for fixed column
1 parent 4fed700 commit 38569c2

18 files changed

+613
-235
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import type { Ref } from 'vue';
2+
import { onBeforeUnmount, ref } from 'vue';
3+
import wrapperRaf from '../raf';
4+
5+
export type Updater<State> = (prev: State) => State;
6+
/**
7+
* Execute code before next frame but async
8+
*/
9+
export function useLayoutState<State>(
10+
defaultState: State,
11+
): [Ref<State>, (updater: Updater<State>) => void] {
12+
const stateRef = ref(defaultState);
13+
let tempState = stateRef.value;
14+
15+
let updateBatchRef = [];
16+
const rafRef = ref();
17+
function setFrameState(updater: Updater<State>) {
18+
wrapperRaf.cancel(rafRef.value);
19+
updateBatchRef.push(updater);
20+
21+
rafRef.value = wrapperRaf(() => {
22+
const prevBatch = updateBatchRef;
23+
// const prevState = stateRef.value;
24+
updateBatchRef = [];
25+
26+
prevBatch.forEach(batchUpdater => {
27+
tempState = batchUpdater(tempState);
28+
});
29+
30+
// if (tempState !== stateRef.value) {
31+
stateRef.value = tempState;
32+
// }
33+
});
34+
}
35+
36+
onBeforeUnmount(() => {
37+
wrapperRaf.cancel(rafRef.value);
38+
});
39+
40+
return [stateRef as Ref<State>, setFrameState];
41+
}

components/table/style/index.less

Lines changed: 90 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -615,15 +615,6 @@
615615
overflow-x: hidden;
616616
table {
617617
min-width: 100%;
618-
619-
// https://github.com/ant-design/ant-design/issues/14545
620-
// https://github.com/ant-design/ant-design/issues/19491
621-
.@{table-prefix-cls}-fixed-columns-in-body:not([colspan]) {
622-
color: transparent;
623-
& > * {
624-
visibility: hidden;
625-
}
626-
}
627618
}
628619
}
629620

@@ -776,6 +767,96 @@
776767
&-row[class*='@{table-prefix-cls}-row-level-0'] .@{table-prefix-cls}-selection-column > span {
777768
display: inline-block;
778769
}
770+
771+
// ============================ Fixed =============================
772+
&-cell-fix-left,
773+
&-cell-fix-right {
774+
position: -webkit-sticky !important;
775+
position: sticky !important;
776+
z-index: @zindex-table-fixed;
777+
background: @table-bg;
778+
}
779+
780+
&-cell-fix-left-first::after,
781+
&-cell-fix-left-last::after {
782+
position: absolute;
783+
top: 0;
784+
right: 0;
785+
bottom: -1px;
786+
width: 30px;
787+
transform: translateX(100%);
788+
transition: box-shadow 0.3s;
789+
content: '';
790+
pointer-events: none;
791+
}
792+
793+
&-cell-fix-right-first::after,
794+
&-cell-fix-right-last::after {
795+
position: absolute;
796+
top: 0;
797+
bottom: -1px;
798+
left: 0;
799+
width: 30px;
800+
transform: translateX(-100%);
801+
transition: box-shadow 0.3s;
802+
content: '';
803+
pointer-events: none;
804+
}
805+
806+
.@{table-prefix-cls}-container {
807+
&::before,
808+
&::after {
809+
position: absolute;
810+
top: 0;
811+
bottom: 0;
812+
z-index: 1;
813+
width: 30px;
814+
transition: box-shadow 0.3s;
815+
content: '';
816+
pointer-events: none;
817+
}
818+
819+
&::before {
820+
left: 0;
821+
}
822+
&::after {
823+
right: 0;
824+
}
825+
}
826+
827+
&-ping-left {
828+
&:not(.@{table-prefix-cls}-has-fix-left) .@{table-prefix-cls}-container {
829+
position: relative;
830+
831+
&::before {
832+
box-shadow: inset 10px 0 8px -8px darken(@shadow-color, 5%);
833+
}
834+
}
835+
836+
.@{table-prefix-cls}-cell-fix-left-first::after,
837+
.@{table-prefix-cls}-cell-fix-left-last::after {
838+
box-shadow: inset 10px 0 8px -8px darken(@shadow-color, 5%);
839+
}
840+
841+
.@{table-prefix-cls}-cell-fix-left-last::before {
842+
background-color: transparent !important;
843+
}
844+
}
845+
846+
&-ping-right {
847+
&:not(.@{table-prefix-cls}-has-fix-right) .@{table-prefix-cls}-container {
848+
position: relative;
849+
850+
&::after {
851+
box-shadow: inset -10px 0 8px -8px darken(@shadow-color, 5%);
852+
}
853+
}
854+
855+
.@{table-prefix-cls}-cell-fix-right-first::after,
856+
.@{table-prefix-cls}-cell-fix-right-last::after {
857+
box-shadow: inset -10px 0 8px -8px darken(@shadow-color, 5%);
858+
}
859+
}
779860
}
780861

781862
.@{table-prefix-cls}-filter-dropdown,

components/vc-table/src/BaseTable.jsx

Lines changed: 7 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -27,15 +27,10 @@ const BaseTable = {
2727
},
2828
methods: {
2929
getColumns(cols) {
30-
const { columns = [], fixed } = this.$props;
31-
const { table } = this;
32-
const { prefixCls } = table.$props;
30+
const { columns = [] } = this.$props;
3331
return (cols || columns).map(column => ({
3432
...column,
35-
className:
36-
!!column.fixed && !fixed
37-
? classNames(`${prefixCls}-fixed-columns-in-body`, column.className, column.class)
38-
: classNames(column.className, column.class),
33+
className: classNames(column.className, column.class),
3934
}));
4035
},
4136
handleRowHover(isHover, key) {
@@ -44,7 +39,6 @@ const BaseTable = {
4439

4540
renderRows(renderData, indent, ancestorKeys = []) {
4641
const {
47-
columnManager,
4842
sComponents: components,
4943
prefixCls,
5044
childrenColumnName,
@@ -57,6 +51,7 @@ const BaseTable = {
5751
onRowMouseLeave = noop,
5852
rowRef,
5953
} = { ...this.table.$attrs, ...this.table.$props, ...this.table.$data };
54+
const { columnManager } = this.store;
6055
const { getRowKey, fixed, expander, isAnyColumnsFixed } = this;
6156

6257
const rows = [];
@@ -68,17 +63,17 @@ const BaseTable = {
6863
typeof rowClassName === 'string' ? rowClassName : rowClassName(record, i, indent);
6964

7065
const onHoverProps = {};
71-
if (columnManager.isAnyColumnsFixed()) {
66+
if (columnManager.isAnyColumnsFixed) {
7267
onHoverProps.onHover = this.handleRowHover;
7368
}
7469

7570
let leafColumns;
7671
if (fixed === 'left') {
77-
leafColumns = columnManager.leftLeafColumns();
72+
leafColumns = columnManager.leftLeafColumns;
7873
} else if (fixed === 'right') {
79-
leafColumns = columnManager.rightLeafColumns();
74+
leafColumns = columnManager.rightLeafColumns;
8075
} else {
81-
leafColumns = this.getColumns(columnManager.leafColumns());
76+
leafColumns = this.getColumns(columnManager.leafColumns);
8277
}
8378

8479
const rowPrefixCls = `${prefixCls}-row`;

components/vc-table/src/ColGroup.jsx

Lines changed: 21 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { inject } from 'vue';
22
import PropTypes from '../../_util/vue-types';
33
import { INTERNAL_COL_DEFINE } from './utils';
4+
import ResizeObserver from '../../vc-resize-observer';
45

56
export default {
67
name: 'ColGroup',
@@ -12,11 +13,12 @@ export default {
1213
setup() {
1314
return {
1415
table: inject('table', {}),
16+
store: inject('table-store', () => ({})),
1517
};
1618
},
1719
render() {
1820
const { fixed, table } = this;
19-
const { prefixCls, expandIconAsCell, columnManager } = table;
21+
const { prefixCls, expandIconAsCell, onColumnResize } = table;
2022

2123
let cols = [];
2224

@@ -25,19 +27,32 @@ export default {
2527
}
2628

2729
let leafColumns;
28-
30+
const { columnManager } = this.store;
2931
if (fixed === 'left') {
30-
leafColumns = columnManager.leftLeafColumns();
32+
leafColumns = columnManager.leftLeafColumns;
3133
} else if (fixed === 'right') {
32-
leafColumns = columnManager.rightLeafColumns();
34+
leafColumns = columnManager.rightLeafColumns;
3335
} else {
34-
leafColumns = columnManager.leafColumns();
36+
leafColumns = columnManager.leafColumns;
3537
}
3638
cols = cols.concat(
3739
leafColumns.map(({ key, dataIndex, width, [INTERNAL_COL_DEFINE]: additionalProps }) => {
3840
const mergedKey = key !== undefined ? key : dataIndex;
3941
const w = typeof width === 'number' ? `${width}px` : width;
40-
return <col key={mergedKey} style={{ width: w, minWidth: w }} {...additionalProps} />;
42+
return (
43+
<ResizeObserver
44+
onResize={({ offsetWidth }) => {
45+
onColumnResize(mergedKey, offsetWidth);
46+
}}
47+
>
48+
<col
49+
data-key={mergedKey}
50+
key={mergedKey}
51+
style={{ width: w, minWidth: w }}
52+
{...additionalProps}
53+
/>
54+
</ResizeObserver>
55+
);
4156
}),
4257
);
4358
return <colgroup>{cols}</colgroup>;

components/vc-table/src/ColumnManager.jsx

Lines changed: 0 additions & 116 deletions
This file was deleted.

0 commit comments

Comments
 (0)