Skip to content

Commit

Permalink
perf: table use sticky for fixed column
Browse files Browse the repository at this point in the history
  • Loading branch information
tangjinzhou committed Aug 6, 2021
1 parent 4fed700 commit 38569c2
Show file tree
Hide file tree
Showing 18 changed files with 613 additions and 235 deletions.
41 changes: 41 additions & 0 deletions components/_util/hooks/useLayoutState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import type { Ref } from 'vue';
import { onBeforeUnmount, ref } from 'vue';
import wrapperRaf from '../raf';

export type Updater<State> = (prev: State) => State;
/**
* Execute code before next frame but async
*/
export function useLayoutState<State>(
defaultState: State,
): [Ref<State>, (updater: Updater<State>) => void] {
const stateRef = ref(defaultState);
let tempState = stateRef.value;

let updateBatchRef = [];
const rafRef = ref();
function setFrameState(updater: Updater<State>) {
wrapperRaf.cancel(rafRef.value);
updateBatchRef.push(updater);

rafRef.value = wrapperRaf(() => {
const prevBatch = updateBatchRef;
// const prevState = stateRef.value;
updateBatchRef = [];

prevBatch.forEach(batchUpdater => {
tempState = batchUpdater(tempState);
});

// if (tempState !== stateRef.value) {
stateRef.value = tempState;
// }
});
}

onBeforeUnmount(() => {
wrapperRaf.cancel(rafRef.value);
});

return [stateRef as Ref<State>, setFrameState];
}
99 changes: 90 additions & 9 deletions components/table/style/index.less
Original file line number Diff line number Diff line change
Expand Up @@ -615,15 +615,6 @@
overflow-x: hidden;
table {
min-width: 100%;

// https://github.com/ant-design/ant-design/issues/14545
// https://github.com/ant-design/ant-design/issues/19491
.@{table-prefix-cls}-fixed-columns-in-body:not([colspan]) {
color: transparent;
& > * {
visibility: hidden;
}
}
}
}

Expand Down Expand Up @@ -776,6 +767,96 @@
&-row[class*='@{table-prefix-cls}-row-level-0'] .@{table-prefix-cls}-selection-column > span {
display: inline-block;
}

// ============================ Fixed =============================
&-cell-fix-left,
&-cell-fix-right {
position: -webkit-sticky !important;
position: sticky !important;
z-index: @zindex-table-fixed;
background: @table-bg;
}

&-cell-fix-left-first::after,
&-cell-fix-left-last::after {
position: absolute;
top: 0;
right: 0;
bottom: -1px;
width: 30px;
transform: translateX(100%);
transition: box-shadow 0.3s;
content: '';
pointer-events: none;
}

&-cell-fix-right-first::after,
&-cell-fix-right-last::after {
position: absolute;
top: 0;
bottom: -1px;
left: 0;
width: 30px;
transform: translateX(-100%);
transition: box-shadow 0.3s;
content: '';
pointer-events: none;
}

.@{table-prefix-cls}-container {
&::before,
&::after {
position: absolute;
top: 0;
bottom: 0;
z-index: 1;
width: 30px;
transition: box-shadow 0.3s;
content: '';
pointer-events: none;
}

&::before {
left: 0;
}
&::after {
right: 0;
}
}

&-ping-left {
&:not(.@{table-prefix-cls}-has-fix-left) .@{table-prefix-cls}-container {
position: relative;

&::before {
box-shadow: inset 10px 0 8px -8px darken(@shadow-color, 5%);
}
}

.@{table-prefix-cls}-cell-fix-left-first::after,
.@{table-prefix-cls}-cell-fix-left-last::after {
box-shadow: inset 10px 0 8px -8px darken(@shadow-color, 5%);
}

.@{table-prefix-cls}-cell-fix-left-last::before {
background-color: transparent !important;
}
}

&-ping-right {
&:not(.@{table-prefix-cls}-has-fix-right) .@{table-prefix-cls}-container {
position: relative;

&::after {
box-shadow: inset -10px 0 8px -8px darken(@shadow-color, 5%);
}
}

.@{table-prefix-cls}-cell-fix-right-first::after,
.@{table-prefix-cls}-cell-fix-right-last::after {
box-shadow: inset -10px 0 8px -8px darken(@shadow-color, 5%);
}
}
}

.@{table-prefix-cls}-filter-dropdown,
Expand Down
19 changes: 7 additions & 12 deletions components/vc-table/src/BaseTable.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -27,15 +27,10 @@ const BaseTable = {
},
methods: {
getColumns(cols) {
const { columns = [], fixed } = this.$props;
const { table } = this;
const { prefixCls } = table.$props;
const { columns = [] } = this.$props;
return (cols || columns).map(column => ({
...column,
className:
!!column.fixed && !fixed
? classNames(`${prefixCls}-fixed-columns-in-body`, column.className, column.class)
: classNames(column.className, column.class),
className: classNames(column.className, column.class),
}));
},
handleRowHover(isHover, key) {
Expand All @@ -44,7 +39,6 @@ const BaseTable = {

renderRows(renderData, indent, ancestorKeys = []) {
const {
columnManager,
sComponents: components,
prefixCls,
childrenColumnName,
Expand All @@ -57,6 +51,7 @@ const BaseTable = {
onRowMouseLeave = noop,
rowRef,
} = { ...this.table.$attrs, ...this.table.$props, ...this.table.$data };
const { columnManager } = this.store;
const { getRowKey, fixed, expander, isAnyColumnsFixed } = this;

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

const onHoverProps = {};
if (columnManager.isAnyColumnsFixed()) {
if (columnManager.isAnyColumnsFixed) {
onHoverProps.onHover = this.handleRowHover;
}

let leafColumns;
if (fixed === 'left') {
leafColumns = columnManager.leftLeafColumns();
leafColumns = columnManager.leftLeafColumns;
} else if (fixed === 'right') {
leafColumns = columnManager.rightLeafColumns();
leafColumns = columnManager.rightLeafColumns;
} else {
leafColumns = this.getColumns(columnManager.leafColumns());
leafColumns = this.getColumns(columnManager.leafColumns);
}

const rowPrefixCls = `${prefixCls}-row`;
Expand Down
27 changes: 21 additions & 6 deletions components/vc-table/src/ColGroup.jsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { inject } from 'vue';
import PropTypes from '../../_util/vue-types';
import { INTERNAL_COL_DEFINE } from './utils';
import ResizeObserver from '../../vc-resize-observer';

export default {
name: 'ColGroup',
Expand All @@ -12,11 +13,12 @@ export default {
setup() {
return {
table: inject('table', {}),
store: inject('table-store', () => ({})),
};
},
render() {
const { fixed, table } = this;
const { prefixCls, expandIconAsCell, columnManager } = table;
const { prefixCls, expandIconAsCell, onColumnResize } = table;

let cols = [];

Expand All @@ -25,19 +27,32 @@ export default {
}

let leafColumns;

const { columnManager } = this.store;
if (fixed === 'left') {
leafColumns = columnManager.leftLeafColumns();
leafColumns = columnManager.leftLeafColumns;
} else if (fixed === 'right') {
leafColumns = columnManager.rightLeafColumns();
leafColumns = columnManager.rightLeafColumns;
} else {
leafColumns = columnManager.leafColumns();
leafColumns = columnManager.leafColumns;
}
cols = cols.concat(
leafColumns.map(({ key, dataIndex, width, [INTERNAL_COL_DEFINE]: additionalProps }) => {
const mergedKey = key !== undefined ? key : dataIndex;
const w = typeof width === 'number' ? `${width}px` : width;
return <col key={mergedKey} style={{ width: w, minWidth: w }} {...additionalProps} />;
return (
<ResizeObserver
onResize={({ offsetWidth }) => {
onColumnResize(mergedKey, offsetWidth);
}}
>
<col
data-key={mergedKey}
key={mergedKey}
style={{ width: w, minWidth: w }}
{...additionalProps}
/>
</ResizeObserver>
);
}),
);
return <colgroup>{cols}</colgroup>;
Expand Down
116 changes: 0 additions & 116 deletions components/vc-table/src/ColumnManager.jsx

This file was deleted.

Loading

0 comments on commit 38569c2

Please sign in to comment.