perf: table
parent
d3acab2d55
commit
6e85fd92e3
|
@ -3,7 +3,6 @@ import PropTypes, { withUndefined } from '../../_util/vue-types';
|
||||||
import TableCell from './TableCell';
|
import TableCell from './TableCell';
|
||||||
import { initDefaultProps, findDOMNode } from '../../_util/props-util';
|
import { initDefaultProps, findDOMNode } from '../../_util/props-util';
|
||||||
import BaseMixin from '../../_util/BaseMixin';
|
import BaseMixin from '../../_util/BaseMixin';
|
||||||
import warning from '../../_util/warning';
|
|
||||||
import { computed, inject } from 'vue';
|
import { computed, inject } from 'vue';
|
||||||
function noop() {}
|
function noop() {}
|
||||||
const TableRow = {
|
const TableRow = {
|
||||||
|
|
|
@ -35,7 +35,8 @@ import defaultLocale from '../locale/en_US';
|
||||||
import type { SizeType } from '../config-provider';
|
import type { SizeType } from '../config-provider';
|
||||||
import devWarning from '../vc-util/devWarning';
|
import devWarning from '../vc-util/devWarning';
|
||||||
import type { PropType } from 'vue';
|
import type { PropType } from 'vue';
|
||||||
import { computed, defineComponent, ref, toRef, watchEffect } from 'vue';
|
import { reactive } from 'vue';
|
||||||
|
import { computed, defineComponent, toRef, watchEffect } from 'vue';
|
||||||
import type { DefaultRecordType } from '../vc-table/interface';
|
import type { DefaultRecordType } from '../vc-table/interface';
|
||||||
import useBreakpoint from '../_util/hooks/useBreakpoint';
|
import useBreakpoint from '../_util/hooks/useBreakpoint';
|
||||||
import useConfigInject from '../_util/hooks/useConfigInject';
|
import useConfigInject from '../_util/hooks/useConfigInject';
|
||||||
|
@ -43,7 +44,8 @@ import { useLocaleReceiver } from '../locale-provider/LocaleReceiver';
|
||||||
import classNames from '../_util/classNames';
|
import classNames from '../_util/classNames';
|
||||||
import omit from '../_util/omit';
|
import omit from '../_util/omit';
|
||||||
import { initDefaultProps } from '../_util/props-util';
|
import { initDefaultProps } from '../_util/props-util';
|
||||||
import { ContextSlots, useProvideSlots } from './context';
|
import { useProvideSlots } from './context';
|
||||||
|
import type { ContextSlots } from './context';
|
||||||
import useColumns from './hooks/useColumns';
|
import useColumns from './hooks/useColumns';
|
||||||
import { convertChildrenToColumns } from './util';
|
import { convertChildrenToColumns } from './util';
|
||||||
|
|
||||||
|
@ -77,6 +79,7 @@ export interface TableProps<RecordType = DefaultRecordType>
|
||||||
| 'scroll'
|
| 'scroll'
|
||||||
| 'emptyText'
|
| 'emptyText'
|
||||||
| 'canExpandable'
|
| 'canExpandable'
|
||||||
|
| 'onUpdateInternalRefs'
|
||||||
> {
|
> {
|
||||||
dropdownPrefixCls?: string;
|
dropdownPrefixCls?: string;
|
||||||
dataSource?: RcTableProps<RecordType>['data'];
|
dataSource?: RcTableProps<RecordType>['data'];
|
||||||
|
@ -217,11 +220,11 @@ const InteralTable = defineComponent<
|
||||||
}
|
}
|
||||||
>({
|
>({
|
||||||
name: 'InteralTable',
|
name: 'InteralTable',
|
||||||
|
inheritAttrs: false,
|
||||||
props: initDefaultProps(tableProps(), {
|
props: initDefaultProps(tableProps(), {
|
||||||
rowKey: 'key',
|
rowKey: 'key',
|
||||||
}) as any,
|
}) as any,
|
||||||
inheritAttrs: false,
|
// emits: ['expandedRowsChange', 'change', 'expand'],
|
||||||
emits: [],
|
|
||||||
slots: [
|
slots: [
|
||||||
'emptyText',
|
'emptyText',
|
||||||
'expandIcon',
|
'expandIcon',
|
||||||
|
@ -282,8 +285,12 @@ const InteralTable = defineComponent<
|
||||||
return null;
|
return null;
|
||||||
});
|
});
|
||||||
|
|
||||||
const internalRefs = {
|
const internalRefs = reactive({
|
||||||
body: ref<HTMLDivElement>(),
|
body: null,
|
||||||
|
});
|
||||||
|
|
||||||
|
const updateInternalRefs = refs => {
|
||||||
|
Object.assign(internalRefs, refs);
|
||||||
};
|
};
|
||||||
|
|
||||||
// ============================ RowKey ============================
|
// ============================ RowKey ============================
|
||||||
|
@ -325,9 +332,9 @@ const InteralTable = defineComponent<
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (scroll && scroll.scrollToFirstRowOnChange !== false && internalRefs.body.value) {
|
if (scroll && scroll.scrollToFirstRowOnChange !== false && internalRefs.body) {
|
||||||
scrollTo(0, {
|
scrollTo(0, {
|
||||||
getContainer: () => internalRefs.body.value!,
|
getContainer: () => internalRefs.body,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -606,7 +613,8 @@ const InteralTable = defineComponent<
|
||||||
rowClassName={internalRowClassName}
|
rowClassName={internalRowClassName}
|
||||||
// Internal
|
// Internal
|
||||||
internalHooks={INTERNAL_HOOKS}
|
internalHooks={INTERNAL_HOOKS}
|
||||||
internalRefs={internalRefs as any}
|
internalRefs={internalRefs}
|
||||||
|
onUpdateInternalRefs={updateInternalRefs}
|
||||||
transformColumns={transformColumns}
|
transformColumns={transformColumns}
|
||||||
v-slots={{
|
v-slots={{
|
||||||
...slots,
|
...slots,
|
||||||
|
|
|
@ -25,7 +25,7 @@ To fix some columns and scroll inside other columns, and you must set `scroll.x`
|
||||||
</docs>
|
</docs>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<a-table :columns="columns" :data-source="data" :scroll="{ x: 1300 }">
|
<a-table :columns="columns" :data-source="data" :scroll="{ x: 1300, y: 1000 }">
|
||||||
<template #bodyCell="{ column, text }">
|
<template #bodyCell="{ column, text }">
|
||||||
<template v-if="column.key === 'operation'">
|
<template v-if="column.key === 'operation'">
|
||||||
<a>action</a>
|
<a>action</a>
|
||||||
|
|
|
@ -38,6 +38,7 @@ Set summary content by `summary` prop. Sync column fixed status with `a-table-su
|
||||||
</a-table-summary-row>
|
</a-table-summary-row>
|
||||||
</template>
|
</template>
|
||||||
</a-table>
|
</a-table>
|
||||||
|
<br />
|
||||||
<a-table
|
<a-table
|
||||||
:columns="fixedColumns"
|
:columns="fixedColumns"
|
||||||
:data-source="fixedData"
|
:data-source="fixedData"
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import devWarning from '../../vc-util/devWarning';
|
import devWarning from '../../vc-util/devWarning';
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
import { ContextSlots } from '../context';
|
import type { ContextSlots } from '../context';
|
||||||
import type { TransformColumns, ColumnsType } from '../interface';
|
import type { TransformColumns, ColumnsType } from '../interface';
|
||||||
|
|
||||||
function fillSlots<RecordType>(columns: ColumnsType<RecordType>, contextSlots: Ref<ContextSlots>) {
|
function fillSlots<RecordType>(columns: ColumnsType<RecordType>, contextSlots: Ref<ContextSlots>) {
|
||||||
|
|
|
@ -2,7 +2,8 @@ import Table, { tableProps } from './Table';
|
||||||
import Column from './Column';
|
import Column from './Column';
|
||||||
import ColumnGroup from './ColumnGroup';
|
import ColumnGroup from './ColumnGroup';
|
||||||
import type { TableProps, TablePaginationConfig } from './Table';
|
import type { TableProps, TablePaginationConfig } from './Table';
|
||||||
import { App, defineComponent } from 'vue';
|
import { defineComponent } from 'vue';
|
||||||
|
import type { App } from 'vue';
|
||||||
import { Summary, SummaryCell, SummaryRow } from '../vc-table';
|
import { Summary, SummaryCell, SummaryRow } from '../vc-table';
|
||||||
import { SELECTION_ALL, SELECTION_INVERT, SELECTION_NONE } from './hooks/useSelection';
|
import { SELECTION_ALL, SELECTION_INVERT, SELECTION_NONE } from './hooks/useSelection';
|
||||||
|
|
||||||
|
|
|
@ -24,6 +24,8 @@ export interface BodyRowProps<RecordType> {
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineComponent<BodyRowProps<unknown>>({
|
export default defineComponent<BodyRowProps<unknown>>({
|
||||||
|
name: 'BodyRow',
|
||||||
|
inheritAttrs: false,
|
||||||
props: [
|
props: [
|
||||||
'record',
|
'record',
|
||||||
'index',
|
'index',
|
||||||
|
@ -38,8 +40,6 @@ export default defineComponent<BodyRowProps<unknown>>({
|
||||||
'getRowKey',
|
'getRowKey',
|
||||||
'childrenColumnName',
|
'childrenColumnName',
|
||||||
] as any,
|
] as any,
|
||||||
name: 'BodyRow',
|
|
||||||
inheritAttrs: false,
|
|
||||||
setup(props, { attrs }) {
|
setup(props, { attrs }) {
|
||||||
const tableContext = useInjectTable();
|
const tableContext = useInjectTable();
|
||||||
const bodyContext = useInjectBody();
|
const bodyContext = useInjectBody();
|
||||||
|
@ -92,6 +92,7 @@ export default defineComponent<BodyRowProps<unknown>>({
|
||||||
} else if (typeof rowClassName === 'function') {
|
} else if (typeof rowClassName === 'function') {
|
||||||
return rowClassName(record, index, indent);
|
return rowClassName(record, index, indent);
|
||||||
}
|
}
|
||||||
|
return '';
|
||||||
});
|
});
|
||||||
|
|
||||||
const columnsKey = computed(() => getColumnsKey(bodyContext.flattenColumns));
|
const columnsKey = computed(() => getColumnsKey(bodyContext.flattenColumns));
|
||||||
|
|
|
@ -17,6 +17,7 @@ export interface ExpandedRowProps {
|
||||||
|
|
||||||
export default defineComponent<ExpandedRowProps>({
|
export default defineComponent<ExpandedRowProps>({
|
||||||
name: 'ExpandedRow',
|
name: 'ExpandedRow',
|
||||||
|
inheritAttrs: false,
|
||||||
props: [
|
props: [
|
||||||
'prefixCls',
|
'prefixCls',
|
||||||
'component',
|
'component',
|
||||||
|
@ -28,7 +29,6 @@ export default defineComponent<ExpandedRowProps>({
|
||||||
'expanded',
|
'expanded',
|
||||||
'colSpan',
|
'colSpan',
|
||||||
] as any,
|
] as any,
|
||||||
inheritAttrs: false,
|
|
||||||
setup(props, { slots, attrs }) {
|
setup(props, { slots, attrs }) {
|
||||||
const tableContext = useInjectTable();
|
const tableContext = useInjectTable();
|
||||||
return () => {
|
return () => {
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
import { defineComponent, onMounted, ref } from 'vue';
|
||||||
import VCResizeObserver from '../../vc-resize-observer';
|
import VCResizeObserver from '../../vc-resize-observer';
|
||||||
import type { Key } from '../interface';
|
import type { Key } from '../interface';
|
||||||
|
|
||||||
|
@ -6,16 +7,28 @@ export interface MeasureCellProps {
|
||||||
onColumnResize: (key: Key, width: number) => void;
|
onColumnResize: (key: Key, width: number) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function MeasureCell({ columnKey }: MeasureCellProps, { emit }) {
|
export default defineComponent<MeasureCellProps>({
|
||||||
return (
|
name: 'MeasureCell',
|
||||||
<VCResizeObserver
|
props: ['columnKey'] as any,
|
||||||
onResize={({ offsetWidth }) => {
|
setup(props, { emit }) {
|
||||||
emit('columnResize', columnKey, offsetWidth);
|
const tdRef = ref();
|
||||||
}}
|
onMounted(() => {
|
||||||
>
|
if (tdRef.value) {
|
||||||
<td style={{ padding: 0, border: 0, height: 0 }}>
|
emit('columnResize', props.columnKey, tdRef.value.offsetWidth);
|
||||||
<div style={{ height: 0, overflow: 'hidden' }}> </div>
|
}
|
||||||
</td>
|
});
|
||||||
</VCResizeObserver>
|
return () => {
|
||||||
);
|
return (
|
||||||
}
|
<VCResizeObserver
|
||||||
|
onResize={({ offsetWidth }) => {
|
||||||
|
emit('columnResize', props.columnKey, offsetWidth);
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<td ref={tdRef} style={{ padding: 0, border: 0, height: 0 }}>
|
||||||
|
<div style={{ height: 0, overflow: 'hidden' }}> </div>
|
||||||
|
</td>
|
||||||
|
</VCResizeObserver>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
|
@ -107,7 +107,7 @@ export default defineComponent<BodyProps<any>>({
|
||||||
const columnsKey = getColumnsKey(flattenColumns);
|
const columnsKey = getColumnsKey(flattenColumns);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<WrapperComponent className={`${prefixCls}-tbody`}>
|
<WrapperComponent class={`${prefixCls}-tbody`}>
|
||||||
{/* Measure body column width with additional hidden col */}
|
{/* Measure body column width with additional hidden col */}
|
||||||
{measureColumnWidth && (
|
{measureColumnWidth && (
|
||||||
<tr
|
<tr
|
||||||
|
|
|
@ -48,6 +48,7 @@ export interface FixedHeaderProps<RecordType> extends HeaderProps<RecordType> {
|
||||||
|
|
||||||
export default defineComponent<FixedHeaderProps<DefaultRecordType>>({
|
export default defineComponent<FixedHeaderProps<DefaultRecordType>>({
|
||||||
name: 'FixedHolder',
|
name: 'FixedHolder',
|
||||||
|
inheritAttrs: false,
|
||||||
props: [
|
props: [
|
||||||
'columns',
|
'columns',
|
||||||
'flattenColumns',
|
'flattenColumns',
|
||||||
|
@ -64,7 +65,6 @@ export default defineComponent<FixedHeaderProps<DefaultRecordType>>({
|
||||||
'stickyClassName',
|
'stickyClassName',
|
||||||
] as any,
|
] as any,
|
||||||
emits: ['scroll'],
|
emits: ['scroll'],
|
||||||
inheritAttrs: false,
|
|
||||||
setup(props, { attrs, slots, emit }) {
|
setup(props, { attrs, slots, emit }) {
|
||||||
const tableContext = useInjectTable();
|
const tableContext = useInjectTable();
|
||||||
const combinationScrollBarSize = computed(() =>
|
const combinationScrollBarSize = computed(() =>
|
||||||
|
|
|
@ -14,8 +14,8 @@ export interface SummaryCellProps {
|
||||||
|
|
||||||
export default defineComponent<SummaryCellProps>({
|
export default defineComponent<SummaryCellProps>({
|
||||||
name: 'SummaryCell',
|
name: 'SummaryCell',
|
||||||
props: ['index', 'colSpan', 'rowSpan', 'align'] as any,
|
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
|
props: ['index', 'colSpan', 'rowSpan', 'align'] as any,
|
||||||
setup(props, { attrs, slots }) {
|
setup(props, { attrs, slots }) {
|
||||||
const tableContext = useInjectTable();
|
const tableContext = useInjectTable();
|
||||||
const summaryContext = useInjectSummary();
|
const summaryContext = useInjectSummary();
|
||||||
|
|
|
@ -7,8 +7,8 @@ export interface SummaryProps {
|
||||||
|
|
||||||
let indexGuid = 0;
|
let indexGuid = 0;
|
||||||
const Summary = defineComponent<SummaryProps>({
|
const Summary = defineComponent<SummaryProps>({
|
||||||
props: ['fixed'] as any,
|
|
||||||
name: 'Summary',
|
name: 'Summary',
|
||||||
|
props: ['fixed'] as any,
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
const tableContext = useInjectTable();
|
const tableContext = useInjectTable();
|
||||||
const uniKey = `table-summary-uni-key-${++indexGuid}`;
|
const uniKey = `table-summary-uni-key-${++indexGuid}`;
|
||||||
|
|
|
@ -14,8 +14,8 @@ export interface FooterProps<RecordType = DefaultRecordType> {
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'Footer',
|
name: 'Footer',
|
||||||
props: ['stickyOffsets', 'flattenColumns'],
|
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
|
props: ['stickyOffsets', 'flattenColumns'],
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
const tableContext = useInjectTable();
|
const tableContext = useInjectTable();
|
||||||
useProvideSummary(
|
useProvideSummary(
|
||||||
|
|
|
@ -29,7 +29,7 @@ import { getCellFixedInfo } from './utils/fixUtil';
|
||||||
import StickyScrollBar from './stickyScrollBar';
|
import StickyScrollBar from './stickyScrollBar';
|
||||||
import useSticky from './hooks/useSticky';
|
import useSticky from './hooks/useSticky';
|
||||||
import FixedHolder from './FixedHolder';
|
import FixedHolder from './FixedHolder';
|
||||||
import type { CSSProperties, Ref } from 'vue';
|
import type { CSSProperties } from 'vue';
|
||||||
import {
|
import {
|
||||||
computed,
|
computed,
|
||||||
defineComponent,
|
defineComponent,
|
||||||
|
@ -130,18 +130,19 @@ export interface TableProps<RecordType = unknown> {
|
||||||
* !!! DO NOT USE IN PRODUCTION ENVIRONMENT !!!
|
* !!! DO NOT USE IN PRODUCTION ENVIRONMENT !!!
|
||||||
*/
|
*/
|
||||||
internalRefs?: {
|
internalRefs?: {
|
||||||
body: Ref<HTMLDivElement>;
|
body: HTMLDivElement;
|
||||||
};
|
};
|
||||||
|
|
||||||
sticky?: boolean | TableSticky;
|
sticky?: boolean | TableSticky;
|
||||||
|
|
||||||
canExpandable?: boolean;
|
canExpandable?: boolean;
|
||||||
|
|
||||||
|
onUpdateInternalRefs?: (refs: Record<string, any>) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export default defineComponent<TableProps>({
|
export default defineComponent<TableProps>({
|
||||||
name: 'Table',
|
name: 'Table',
|
||||||
slots: ['title', 'footer', 'summary', 'emptyText'],
|
inheritAttrs: false,
|
||||||
emits: ['expand', 'expandedRowsChange'],
|
|
||||||
props: [
|
props: [
|
||||||
'prefixCls',
|
'prefixCls',
|
||||||
'data',
|
'data',
|
||||||
|
@ -178,8 +179,10 @@ export default defineComponent<TableProps>({
|
||||||
'internalHooks',
|
'internalHooks',
|
||||||
'internalRefs',
|
'internalRefs',
|
||||||
'canExpandable',
|
'canExpandable',
|
||||||
|
'onUpdateInternalRefs',
|
||||||
] as any,
|
] as any,
|
||||||
inheritAttrs: false,
|
slots: ['title', 'footer', 'summary', 'emptyText'],
|
||||||
|
emits: ['expand', 'expandedRowsChange', 'updateInternalRefs'],
|
||||||
setup(props, { attrs, slots, emit }) {
|
setup(props, { attrs, slots, emit }) {
|
||||||
const mergedData = computed(() => props.data || EMPTY_DATA);
|
const mergedData = computed(() => props.data || EMPTY_DATA);
|
||||||
const hasData = computed(() => !!mergedData.value.length);
|
const hasData = computed(() => !!mergedData.value.length);
|
||||||
|
@ -466,7 +469,11 @@ export default defineComponent<TableProps>({
|
||||||
watchEffect(
|
watchEffect(
|
||||||
() => {
|
() => {
|
||||||
if (props.internalHooks === INTERNAL_HOOKS && props.internalRefs) {
|
if (props.internalHooks === INTERNAL_HOOKS && props.internalRefs) {
|
||||||
props.internalRefs.body.value = scrollBodyRef.value;
|
props.onUpdateInternalRefs({
|
||||||
|
body: scrollBodyRef.value
|
||||||
|
? (scrollBodyRef.value as any).$el || scrollBodyRef.value
|
||||||
|
: null,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{ flush: 'post' },
|
{ flush: 'post' },
|
||||||
|
@ -545,6 +552,26 @@ export default defineComponent<TableProps>({
|
||||||
onColumnResize,
|
onColumnResize,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Body
|
||||||
|
const bodyTable = () => (
|
||||||
|
<Body
|
||||||
|
data={mergedData.value}
|
||||||
|
measureColumnWidth={fixHeader.value || horizonScroll.value || stickyState.value.isSticky}
|
||||||
|
expandedKeys={mergedExpandedKeys.value}
|
||||||
|
rowExpandable={props.rowExpandable}
|
||||||
|
getRowKey={getRowKey.value}
|
||||||
|
customRow={props.customRow}
|
||||||
|
childrenColumnName={mergedChildrenColumnName.value}
|
||||||
|
v-slots={{ emptyText: emptyNode }}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
|
||||||
|
const bodyColGroup = () => (
|
||||||
|
<ColGroup
|
||||||
|
colWidths={flattenColumns.value.map(({ width }) => width)}
|
||||||
|
columns={flattenColumns.value}
|
||||||
|
/>
|
||||||
|
);
|
||||||
return () => {
|
return () => {
|
||||||
const {
|
const {
|
||||||
prefixCls,
|
prefixCls,
|
||||||
|
@ -560,17 +587,14 @@ export default defineComponent<TableProps>({
|
||||||
id,
|
id,
|
||||||
showHeader,
|
showHeader,
|
||||||
customHeaderRow,
|
customHeaderRow,
|
||||||
rowExpandable,
|
|
||||||
|
|
||||||
customRow,
|
|
||||||
} = props;
|
} = props;
|
||||||
const { isSticky, offsetHeader, offsetSummary, offsetScroll, stickyClassName, container } =
|
const { isSticky, offsetHeader, offsetSummary, offsetScroll, stickyClassName, container } =
|
||||||
stickyState.value;
|
stickyState.value;
|
||||||
const TableComponent = getComponent(['table'], 'table');
|
const TableComponent = getComponent(['table'], 'table');
|
||||||
|
const customizeScrollBody = getComponent(['body']) as unknown as CustomizeScrollBody<any>;
|
||||||
const summaryNode = slots.summary?.({ pageData: mergedData.value });
|
const summaryNode = slots.summary?.({ pageData: mergedData.value });
|
||||||
|
|
||||||
let groupTableNode;
|
let groupTableNode = () => null;
|
||||||
|
|
||||||
// Header props
|
// Header props
|
||||||
const headerProps = {
|
const headerProps = {
|
||||||
|
@ -582,29 +606,6 @@ export default defineComponent<TableProps>({
|
||||||
scroll,
|
scroll,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Body
|
|
||||||
const bodyTable = (
|
|
||||||
<Body
|
|
||||||
data={mergedData.value}
|
|
||||||
measureColumnWidth={fixHeader.value || horizonScroll.value || isSticky}
|
|
||||||
expandedKeys={mergedExpandedKeys.value}
|
|
||||||
rowExpandable={rowExpandable}
|
|
||||||
getRowKey={getRowKey.value}
|
|
||||||
customRow={customRow}
|
|
||||||
childrenColumnName={mergedChildrenColumnName.value}
|
|
||||||
v-slots={{ emptyText: emptyNode }}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const bodyColGroup = (
|
|
||||||
<ColGroup
|
|
||||||
colWidths={flattenColumns.value.map(({ width }) => width)}
|
|
||||||
columns={flattenColumns.value}
|
|
||||||
/>
|
|
||||||
);
|
|
||||||
|
|
||||||
const customizeScrollBody = getComponent(['body']) as unknown as CustomizeScrollBody<any>;
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
process.env.NODE_ENV !== 'production' &&
|
process.env.NODE_ENV !== 'production' &&
|
||||||
typeof customizeScrollBody === 'function' &&
|
typeof customizeScrollBody === 'function' &&
|
||||||
|
@ -615,14 +616,15 @@ export default defineComponent<TableProps>({
|
||||||
}
|
}
|
||||||
if (fixHeader.value || isSticky) {
|
if (fixHeader.value || isSticky) {
|
||||||
// >>>>>> Fixed Header
|
// >>>>>> Fixed Header
|
||||||
let bodyContent;
|
let bodyContent = () => null;
|
||||||
|
|
||||||
if (typeof customizeScrollBody === 'function') {
|
if (typeof customizeScrollBody === 'function') {
|
||||||
bodyContent = customizeScrollBody(mergedData.value, {
|
bodyContent = () =>
|
||||||
scrollbarSize: scrollbarSize.value,
|
customizeScrollBody(mergedData.value, {
|
||||||
ref: scrollBodyRef,
|
scrollbarSize: scrollbarSize.value,
|
||||||
onScroll,
|
ref: scrollBodyRef,
|
||||||
});
|
onScroll,
|
||||||
|
});
|
||||||
|
|
||||||
headerProps.colWidths = flattenColumns.value.map(({ width }, index) => {
|
headerProps.colWidths = flattenColumns.value.map(({ width }, index) => {
|
||||||
const colWidth =
|
const colWidth =
|
||||||
|
@ -638,7 +640,7 @@ export default defineComponent<TableProps>({
|
||||||
return 0;
|
return 0;
|
||||||
}) as number[];
|
}) as number[];
|
||||||
} else {
|
} else {
|
||||||
bodyContent = (
|
bodyContent = () => (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
...scrollXStyle.value,
|
...scrollXStyle.value,
|
||||||
|
@ -654,8 +656,8 @@ export default defineComponent<TableProps>({
|
||||||
tableLayout: mergedTableLayout.value,
|
tableLayout: mergedTableLayout.value,
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
{bodyColGroup}
|
{bodyColGroup()}
|
||||||
{bodyTable}
|
{bodyTable()}
|
||||||
{!fixFooter.value && summaryNode && (
|
{!fixFooter.value && summaryNode && (
|
||||||
<Footer stickyOffsets={stickyOffsets} flattenColumns={flattenColumns.value}>
|
<Footer stickyOffsets={stickyOffsets} flattenColumns={flattenColumns.value}>
|
||||||
{summaryNode}
|
{summaryNode}
|
||||||
|
@ -677,7 +679,7 @@ export default defineComponent<TableProps>({
|
||||||
onScroll,
|
onScroll,
|
||||||
};
|
};
|
||||||
|
|
||||||
groupTableNode = (
|
groupTableNode = () => (
|
||||||
<>
|
<>
|
||||||
{/* Header Table */}
|
{/* Header Table */}
|
||||||
{showHeader !== false && (
|
{showHeader !== false && (
|
||||||
|
@ -700,7 +702,7 @@ export default defineComponent<TableProps>({
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Body Table */}
|
{/* Body Table */}
|
||||||
{bodyContent}
|
{bodyContent()}
|
||||||
|
|
||||||
{/* Summary Table */}
|
{/* Summary Table */}
|
||||||
{fixFooter.value && fixFooter.value !== 'top' && (
|
{fixFooter.value && fixFooter.value !== 'top' && (
|
||||||
|
@ -730,7 +732,7 @@ export default defineComponent<TableProps>({
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
// >>>>>> Unique table
|
// >>>>>> Unique table
|
||||||
groupTableNode = (
|
groupTableNode = () => (
|
||||||
<div
|
<div
|
||||||
style={{
|
style={{
|
||||||
...scrollXStyle.value,
|
...scrollXStyle.value,
|
||||||
|
@ -743,9 +745,9 @@ export default defineComponent<TableProps>({
|
||||||
<TableComponent
|
<TableComponent
|
||||||
style={{ ...scrollTableStyle.value, tableLayout: mergedTableLayout.value }}
|
style={{ ...scrollTableStyle.value, tableLayout: mergedTableLayout.value }}
|
||||||
>
|
>
|
||||||
{bodyColGroup}
|
{bodyColGroup()}
|
||||||
{showHeader !== false && <Header {...headerProps} {...columnContext.value} />}
|
{showHeader !== false && <Header {...headerProps} {...columnContext.value} />}
|
||||||
{bodyTable}
|
{bodyTable()}
|
||||||
{summaryNode && (
|
{summaryNode && (
|
||||||
<Footer stickyOffsets={stickyOffsets.value} flattenColumns={flattenColumns.value}>
|
<Footer stickyOffsets={stickyOffsets.value} flattenColumns={flattenColumns.value}>
|
||||||
{summaryNode}
|
{summaryNode}
|
||||||
|
@ -756,7 +758,7 @@ export default defineComponent<TableProps>({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
const ariaProps = getDataAndAriaProps(attrs);
|
const ariaProps = getDataAndAriaProps(attrs);
|
||||||
let fullTable = (
|
const fullTable = () => (
|
||||||
<div
|
<div
|
||||||
{...ariaProps}
|
{...ariaProps}
|
||||||
class={classNames(prefixCls, {
|
class={classNames(prefixCls, {
|
||||||
|
@ -779,15 +781,20 @@ export default defineComponent<TableProps>({
|
||||||
ref={fullTableRef}
|
ref={fullTableRef}
|
||||||
>
|
>
|
||||||
{title && <Panel class={`${prefixCls}-title`}>{title(mergedData.value)}</Panel>}
|
{title && <Panel class={`${prefixCls}-title`}>{title(mergedData.value)}</Panel>}
|
||||||
<div class={`${prefixCls}-container`}>{groupTableNode}</div>
|
<div class={`${prefixCls}-container`}>{groupTableNode()}</div>
|
||||||
{footer && <Panel class={`${prefixCls}-footer`}>{footer(mergedData.value)}</Panel>}
|
{footer && <Panel class={`${prefixCls}-footer`}>{footer(mergedData.value)}</Panel>}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
|
||||||
if (horizonScroll.value) {
|
if (horizonScroll.value) {
|
||||||
fullTable = <VCResizeObserver onResize={onFullTableResize}>{fullTable}</VCResizeObserver>;
|
return (
|
||||||
|
<VCResizeObserver
|
||||||
|
onResize={onFullTableResize}
|
||||||
|
v-slots={{ default: fullTable }}
|
||||||
|
></VCResizeObserver>
|
||||||
|
);
|
||||||
}
|
}
|
||||||
return fullTable;
|
return fullTable();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
import type { Ref, UnwrapRef } from 'vue';
|
import type { Ref, UnwrapRef } from 'vue';
|
||||||
import { getCurrentInstance, onBeforeUnmount, ref } from 'vue';
|
import { onBeforeUnmount, ref } from 'vue';
|
||||||
|
|
||||||
export type Updater<State> = (prev: State) => State;
|
export type Updater<State> = (prev: State) => State;
|
||||||
|
|
||||||
|
@ -14,7 +14,6 @@ export function useLayoutState<State>(
|
||||||
|
|
||||||
const lastPromiseRef = ref<Promise<void>>(null);
|
const lastPromiseRef = ref<Promise<void>>(null);
|
||||||
const updateBatchRef = ref<Updater<State>[]>([]);
|
const updateBatchRef = ref<Updater<State>[]>([]);
|
||||||
const instance = getCurrentInstance();
|
|
||||||
function setFrameState(updater: Updater<State>) {
|
function setFrameState(updater: Updater<State>) {
|
||||||
updateBatchRef.value.push(updater);
|
updateBatchRef.value.push(updater);
|
||||||
|
|
||||||
|
@ -24,7 +23,7 @@ export function useLayoutState<State>(
|
||||||
promise.then(() => {
|
promise.then(() => {
|
||||||
if (lastPromiseRef.value === promise) {
|
if (lastPromiseRef.value === promise) {
|
||||||
const prevBatch = updateBatchRef.value;
|
const prevBatch = updateBatchRef.value;
|
||||||
const prevState = stateRef.value;
|
// const prevState = stateRef.value;
|
||||||
updateBatchRef.value = [];
|
updateBatchRef.value = [];
|
||||||
|
|
||||||
prevBatch.forEach(batchUpdater => {
|
prevBatch.forEach(batchUpdater => {
|
||||||
|
@ -32,10 +31,6 @@ export function useLayoutState<State>(
|
||||||
});
|
});
|
||||||
|
|
||||||
lastPromiseRef.value = null;
|
lastPromiseRef.value = null;
|
||||||
|
|
||||||
if (prevState !== stateRef.value) {
|
|
||||||
instance.update();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,9 @@ interface StickyScrollBarProps {
|
||||||
|
|
||||||
export default defineComponent<StickyScrollBarProps>({
|
export default defineComponent<StickyScrollBarProps>({
|
||||||
name: 'StickyScrollBar',
|
name: 'StickyScrollBar',
|
||||||
|
inheritAttrs: false,
|
||||||
props: ['offsetScroll', 'container', 'scrollBodyRef'] as any,
|
props: ['offsetScroll', 'container', 'scrollBodyRef'] as any,
|
||||||
emits: ['scroll'],
|
emits: ['scroll'],
|
||||||
inheritAttrs: false,
|
|
||||||
setup(props, { emit, expose }) {
|
setup(props, { emit, expose }) {
|
||||||
const tableContext = useInjectTable();
|
const tableContext = useInjectTable();
|
||||||
const bodyScrollWidth = computed(() => props.scrollBodyRef.value.scrollWidth || 0);
|
const bodyScrollWidth = computed(() => props.scrollBodyRef.value.scrollWidth || 0);
|
||||||
|
|
Loading…
Reference in New Issue