refactor: table
parent
a64ed0d623
commit
915100e3bb
|
@ -0,0 +1,42 @@
|
||||||
|
import { isRef, reactive } from 'vue';
|
||||||
|
import type { Ref } from 'vue';
|
||||||
|
type MaybeRef<T> = T | Ref<T>;
|
||||||
|
/**
|
||||||
|
* Converts ref to reactive.
|
||||||
|
*
|
||||||
|
* @see https://vueuse.org/toReactive
|
||||||
|
* @param objectRef A ref of object
|
||||||
|
*/
|
||||||
|
export function toReactive<T extends object>(objectRef: MaybeRef<T>): T {
|
||||||
|
if (!isRef(objectRef)) return reactive(objectRef) as T;
|
||||||
|
|
||||||
|
const proxy = new Proxy(
|
||||||
|
{},
|
||||||
|
{
|
||||||
|
get(_, p, receiver) {
|
||||||
|
return Reflect.get(objectRef.value, p, receiver);
|
||||||
|
},
|
||||||
|
set(_, p, value) {
|
||||||
|
(objectRef.value as any)[p] = value;
|
||||||
|
return true;
|
||||||
|
},
|
||||||
|
deleteProperty(_, p) {
|
||||||
|
return Reflect.deleteProperty(objectRef.value, p);
|
||||||
|
},
|
||||||
|
has(_, p) {
|
||||||
|
return Reflect.has(objectRef.value, p);
|
||||||
|
},
|
||||||
|
ownKeys() {
|
||||||
|
return Object.keys(objectRef.value);
|
||||||
|
},
|
||||||
|
getOwnPropertyDescriptor() {
|
||||||
|
return {
|
||||||
|
enumerable: true,
|
||||||
|
configurable: true,
|
||||||
|
};
|
||||||
|
},
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
return reactive(proxy) as T;
|
||||||
|
}
|
|
@ -50,6 +50,7 @@ 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';
|
||||||
|
|
||||||
export type { ColumnsType, TablePaginationConfig };
|
export type { ColumnsType, TablePaginationConfig };
|
||||||
|
|
||||||
|
@ -106,46 +107,78 @@ export interface TableProps<RecordType = DefaultRecordType>
|
||||||
sortDirections?: SortOrder[];
|
sortDirections?: SortOrder[];
|
||||||
showSorterTooltip?: boolean | TooltipProps;
|
showSorterTooltip?: boolean | TooltipProps;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tableProps = () => {
|
const tableProps = () => {
|
||||||
return {
|
return {
|
||||||
prefixCls: { type: String as PropType<string> },
|
prefixCls: { type: String as PropType<string>, default: undefined },
|
||||||
columns: { type: Array as PropType<ColumnsType> },
|
columns: { type: Array as PropType<ColumnsType>, default: undefined },
|
||||||
rowKey: { type: [String, Function] as PropType<TableProps['rowKey']> },
|
rowKey: { type: [String, Function] as PropType<TableProps['rowKey']>, default: undefined },
|
||||||
tableLayout: { type: String as PropType<TableProps['tableLayout']> },
|
tableLayout: { type: String as PropType<TableProps['tableLayout']>, default: undefined },
|
||||||
rowClassName: { type: String as PropType<TableProps['rowClassName']> },
|
rowClassName: { type: String as PropType<TableProps['rowClassName']>, default: undefined },
|
||||||
title: { type: Function as PropType<TableProps['title']> },
|
title: { type: Function as PropType<TableProps['title']>, default: undefined },
|
||||||
footer: { type: Function as PropType<TableProps['footer']> },
|
footer: { type: Function as PropType<TableProps['footer']>, default: undefined },
|
||||||
id: { type: String as PropType<TableProps['id']> },
|
id: { type: String as PropType<TableProps['id']>, default: undefined },
|
||||||
showHeader: { type: Boolean as PropType<TableProps['showHeader']> },
|
showHeader: { type: Boolean as PropType<TableProps['showHeader']>, default: undefined },
|
||||||
components: { type: Object as PropType<TableProps['components']> },
|
components: { type: Object as PropType<TableProps['components']>, default: undefined },
|
||||||
customRow: { type: Function as PropType<TableProps['customRow']> },
|
customRow: { type: Function as PropType<TableProps['customRow']>, default: undefined },
|
||||||
customHeaderRow: { type: Function as PropType<TableProps['customHeaderRow']> },
|
customHeaderRow: {
|
||||||
direction: { type: String as PropType<TableProps['direction']> },
|
type: Function as PropType<TableProps['customHeaderRow']>,
|
||||||
expandFixed: { type: Boolean as PropType<TableProps['expandFixed']> },
|
default: undefined,
|
||||||
expandColumnWidth: { type: Number as PropType<TableProps['expandColumnWidth']> },
|
},
|
||||||
expandedRowKeys: { type: Array as PropType<TableProps['expandedRowKeys']> },
|
direction: { type: String as PropType<TableProps['direction']>, default: undefined },
|
||||||
defaultExpandedRowKeys: { type: Array as PropType<TableProps['defaultExpandedRowKeys']> },
|
expandFixed: { type: Boolean as PropType<TableProps['expandFixed']>, default: undefined },
|
||||||
expandedRowRender: { type: Function as PropType<TableProps['expandedRowRender']> },
|
expandColumnWidth: {
|
||||||
expandRowByClick: { type: Boolean as PropType<TableProps['expandRowByClick']> },
|
type: Number as PropType<TableProps['expandColumnWidth']>,
|
||||||
expandIcon: { type: Function as PropType<TableProps['expandIcon']> },
|
default: undefined,
|
||||||
onExpand: { type: Function as PropType<TableProps['onExpand']> },
|
},
|
||||||
onExpandedRowsChange: { type: Function as PropType<TableProps['onExpandedRowsChange']> },
|
expandedRowKeys: { type: Array as PropType<TableProps['expandedRowKeys']>, default: undefined },
|
||||||
defaultExpandAllRows: { type: Boolean as PropType<TableProps['defaultExpandAllRows']> },
|
defaultExpandedRowKeys: {
|
||||||
indentSize: { type: Number as PropType<TableProps['indentSize']> },
|
type: Array as PropType<TableProps['defaultExpandedRowKeys']>,
|
||||||
expandIconColumnIndex: { type: Number as PropType<TableProps['expandIconColumnIndex']> },
|
default: undefined,
|
||||||
expandedRowClassName: { type: Function as PropType<TableProps['expandedRowClassName']> },
|
},
|
||||||
childrenColumnName: { type: String as PropType<TableProps['childrenColumnName']> },
|
expandedRowRender: {
|
||||||
rowExpandable: { type: Function as PropType<TableProps['rowExpandable']> },
|
type: Function as PropType<TableProps['expandedRowRender']>,
|
||||||
sticky: { type: String as PropType<TableProps['sticky']> },
|
default: undefined,
|
||||||
|
},
|
||||||
|
expandRowByClick: {
|
||||||
|
type: Boolean as PropType<TableProps['expandRowByClick']>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
expandIcon: { type: Function as PropType<TableProps['expandIcon']>, default: undefined },
|
||||||
|
onExpand: { type: Function as PropType<TableProps['onExpand']>, default: undefined },
|
||||||
|
onExpandedRowsChange: {
|
||||||
|
type: Function as PropType<TableProps['onExpandedRowsChange']>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
defaultExpandAllRows: {
|
||||||
|
type: Boolean as PropType<TableProps['defaultExpandAllRows']>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
indentSize: { type: Number as PropType<TableProps['indentSize']>, default: undefined },
|
||||||
|
expandIconColumnIndex: {
|
||||||
|
type: Number as PropType<TableProps['expandIconColumnIndex']>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
expandedRowClassName: {
|
||||||
|
type: Function as PropType<TableProps['expandedRowClassName']>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
childrenColumnName: {
|
||||||
|
type: String as PropType<TableProps['childrenColumnName']>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
rowExpandable: { type: Function as PropType<TableProps['rowExpandable']>, default: undefined },
|
||||||
|
sticky: { type: String as PropType<TableProps['sticky']>, default: undefined },
|
||||||
|
|
||||||
dropdownPrefixCls: String,
|
dropdownPrefixCls: String,
|
||||||
dataSource: { type: Array as PropType<RcTableProps['data']> },
|
dataSource: { type: Array as PropType<RcTableProps['data']>, default: undefined },
|
||||||
pagination: { type: [Boolean, Object] as PropType<false | TablePaginationConfig> },
|
pagination: {
|
||||||
loading: { type: [Boolean, Object] as PropType<false | SpinProps> },
|
type: [Boolean, Object] as PropType<false | TablePaginationConfig>,
|
||||||
size: { type: String as PropType<SizeType> },
|
default: undefined,
|
||||||
|
},
|
||||||
|
loading: { type: [Boolean, Object] as PropType<false | SpinProps>, default: undefined },
|
||||||
|
size: { type: String as PropType<SizeType>, default: undefined },
|
||||||
bordered: Boolean,
|
bordered: Boolean,
|
||||||
locale: { type: Object as PropType<TableLocale> },
|
locale: { type: Object as PropType<TableLocale>, default: undefined },
|
||||||
|
|
||||||
onChange: {
|
onChange: {
|
||||||
type: Function as PropType<
|
type: Function as PropType<
|
||||||
|
@ -156,30 +189,53 @@ const tableProps = () => {
|
||||||
extra: TableCurrentDataSource,
|
extra: TableCurrentDataSource,
|
||||||
) => void
|
) => void
|
||||||
>,
|
>,
|
||||||
|
default: undefined,
|
||||||
},
|
},
|
||||||
|
|
||||||
rowSelection: { type: Object as PropType<TableRowSelection> },
|
rowSelection: { type: Object as PropType<TableRowSelection>, default: undefined },
|
||||||
getPopupContainer: { type: Function as PropType<GetPopupContainer> },
|
getPopupContainer: { type: Function as PropType<GetPopupContainer>, default: undefined },
|
||||||
scroll: {
|
scroll: {
|
||||||
type: Object as PropType<
|
type: Object as PropType<
|
||||||
RcTableProps['scroll'] & {
|
RcTableProps['scroll'] & {
|
||||||
scrollToFirstRowOnChange?: boolean;
|
scrollToFirstRowOnChange?: boolean;
|
||||||
}
|
}
|
||||||
>,
|
>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
sortDirections: { type: Array as PropType<SortOrder[]>, default: undefined },
|
||||||
|
showSorterTooltip: {
|
||||||
|
type: [Boolean, Object] as PropType<boolean | TooltipProps>,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
contextSlots: {
|
||||||
|
type: Object as PropType<ContextSlots>,
|
||||||
},
|
},
|
||||||
sortDirections: { type: Array as PropType<SortOrder[]> },
|
|
||||||
showSorterTooltip: { type: [Boolean, Object] as PropType<boolean | TooltipProps> },
|
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
const InteralTable = defineComponent<TableProps>({
|
const InteralTable = defineComponent<
|
||||||
|
TableProps & {
|
||||||
|
contextSlots: ContextSlots;
|
||||||
|
}
|
||||||
|
>({
|
||||||
name: 'InteralTable',
|
name: 'InteralTable',
|
||||||
props: initDefaultProps(tableProps(), {
|
props: initDefaultProps(tableProps(), {
|
||||||
rowKey: 'key',
|
rowKey: 'key',
|
||||||
}) as any,
|
}) as any,
|
||||||
inheritAttrs: false,
|
inheritAttrs: false,
|
||||||
emits: [],
|
emits: [],
|
||||||
slots: ['emptyText', 'expandIcon', 'title', 'footer', 'summary'],
|
slots: [
|
||||||
|
'emptyText',
|
||||||
|
'expandIcon',
|
||||||
|
'title',
|
||||||
|
'footer',
|
||||||
|
'summary',
|
||||||
|
'expandedRowRender',
|
||||||
|
'bodyCell',
|
||||||
|
'headerCell',
|
||||||
|
'customFilterIcon',
|
||||||
|
'customFilterDropdown',
|
||||||
|
],
|
||||||
setup(props, { attrs, slots, emit }) {
|
setup(props, { attrs, slots, emit }) {
|
||||||
devWarning(
|
devWarning(
|
||||||
!(typeof props.rowKey === 'function' && props.rowKey.length > 1),
|
!(typeof props.rowKey === 'function' && props.rowKey.length > 1),
|
||||||
|
@ -187,6 +243,8 @@ const InteralTable = defineComponent<TableProps>({
|
||||||
'`index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected.',
|
'`index` parameter of `rowKey` function is deprecated. There is no guarantee that it will work as expected.',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
useProvideSlots(computed(() => props.contextSlots));
|
||||||
|
|
||||||
const screens = useBreakpoint();
|
const screens = useBreakpoint();
|
||||||
|
|
||||||
const mergedColumns = computed(() => {
|
const mergedColumns = computed(() => {
|
||||||
|
@ -339,7 +397,7 @@ const InteralTable = defineComponent<TableProps>({
|
||||||
const columnTitleProps = computed(() => ({
|
const columnTitleProps = computed(() => ({
|
||||||
...sorterTitleProps.value,
|
...sorterTitleProps.value,
|
||||||
}));
|
}));
|
||||||
const [transformTitleColumns] = useTitleColumns(columnTitleProps);
|
const [transformTitleColumns] = useTitleColumns(columnTitleProps, toRef(props, 'contextSlots'));
|
||||||
|
|
||||||
// ========================== Pagination ==========================
|
// ========================== Pagination ==========================
|
||||||
const onPaginationChange = (current: number, pageSize: number) => {
|
const onPaginationChange = (current: number, pageSize: number) => {
|
||||||
|
@ -445,10 +503,12 @@ const InteralTable = defineComponent<TableProps>({
|
||||||
return typeof props.indentSize === 'number' ? props.indentSize : 15;
|
return typeof props.indentSize === 'number' ? props.indentSize : 15;
|
||||||
});
|
});
|
||||||
|
|
||||||
const transformColumns = (innerColumns: ColumnsType<any>): ColumnsType<any> =>
|
const transformColumns = (innerColumns: ColumnsType<any>): ColumnsType<any> => {
|
||||||
transformTitleColumns(
|
const res = transformTitleColumns(
|
||||||
transformSelectionColumns(transformFilterColumns(transformSorterColumns(innerColumns))),
|
transformSelectionColumns(transformFilterColumns(transformSorterColumns(innerColumns))),
|
||||||
);
|
);
|
||||||
|
return res;
|
||||||
|
};
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
const {
|
const {
|
||||||
|
@ -522,6 +582,7 @@ const InteralTable = defineComponent<TableProps>({
|
||||||
<Spin spinning={false} {...spinProps}>
|
<Spin spinning={false} {...spinProps}>
|
||||||
{topPaginationNode}
|
{topPaginationNode}
|
||||||
<RcTable
|
<RcTable
|
||||||
|
{...attrs}
|
||||||
{...tableProps}
|
{...tableProps}
|
||||||
expandIconColumnIndex={expandIconColumnIndex.value}
|
expandIconColumnIndex={expandIconColumnIndex.value}
|
||||||
indentSize={indentSize.value}
|
indentSize={indentSize.value}
|
||||||
|
@ -562,7 +623,16 @@ const Table = defineComponent<TableProps>({
|
||||||
setup(_props, { attrs, slots }) {
|
setup(_props, { attrs, slots }) {
|
||||||
return () => {
|
return () => {
|
||||||
const columns = (attrs.columns || convertChildrenToColumns(slots.default?.())) as ColumnsType;
|
const columns = (attrs.columns || convertChildrenToColumns(slots.default?.())) as ColumnsType;
|
||||||
return <InteralTable {...attrs} columns={columns || []} v-slots={slots} />;
|
console.log('slots', slots);
|
||||||
|
return (
|
||||||
|
<InteralTable
|
||||||
|
{...attrs}
|
||||||
|
columns={columns || []}
|
||||||
|
expandedRowRender={slots.expandedRowRender}
|
||||||
|
contextSlots={{ ...slots }} // use new object, 否则slot热更新失效,原因需进一步探究
|
||||||
|
v-slots={slots}
|
||||||
|
/>
|
||||||
|
);
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
|
@ -0,0 +1,29 @@
|
||||||
|
import type { ComputedRef, InjectionKey } from 'vue';
|
||||||
|
import { computed } from 'vue';
|
||||||
|
import { inject, provide } from 'vue';
|
||||||
|
|
||||||
|
export type ContextSlots = {
|
||||||
|
emptyText?: (...args: any[]) => void;
|
||||||
|
expandIcon?: (...args: any[]) => void;
|
||||||
|
title?: (...args: any[]) => void;
|
||||||
|
footer?: (...args: any[]) => void;
|
||||||
|
summary?: (...args: any[]) => void;
|
||||||
|
bodyCell?: (...args: any[]) => void;
|
||||||
|
headerCell?: (...args: any[]) => void;
|
||||||
|
customFilterIcon?: (...args: any[]) => void;
|
||||||
|
customFilterDropdown?: (...args: any[]) => void;
|
||||||
|
// 兼容 2.x 的 columns slots 配置
|
||||||
|
[key: string]: (...args: any[]) => void;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type ContextProps = ComputedRef<ContextSlots>;
|
||||||
|
|
||||||
|
export const ContextKey: InjectionKey<ContextProps> = Symbol('ContextProps');
|
||||||
|
|
||||||
|
export const useProvideSlots = (props: ContextProps) => {
|
||||||
|
provide(ContextKey, props);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const useInjectSlots = () => {
|
||||||
|
return inject(ContextKey, computed(() => ({})) as ContextProps);
|
||||||
|
};
|
|
@ -18,6 +18,7 @@ import type { FilterState } from '.';
|
||||||
import { computed, defineComponent, onBeforeUnmount, ref } from 'vue';
|
import { computed, defineComponent, onBeforeUnmount, ref } from 'vue';
|
||||||
import classNames from '../../../_util/classNames';
|
import classNames from '../../../_util/classNames';
|
||||||
import useConfigInject from '../../../_util/hooks/useConfigInject';
|
import useConfigInject from '../../../_util/hooks/useConfigInject';
|
||||||
|
import { useInjectSlots } from '../../context';
|
||||||
|
|
||||||
const { SubMenu, Item: MenuItem } = Menu;
|
const { SubMenu, Item: MenuItem } = Menu;
|
||||||
|
|
||||||
|
@ -119,6 +120,7 @@ export default defineComponent<FilterDropdownProps<any>>({
|
||||||
'getPopupContainer',
|
'getPopupContainer',
|
||||||
] as any,
|
] as any,
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
|
const contextSlots = useInjectSlots();
|
||||||
const filterDropdownVisible = computed(() => props.column.filterDropdownVisible);
|
const filterDropdownVisible = computed(() => props.column.filterDropdownVisible);
|
||||||
const visible = ref(false);
|
const visible = ref(false);
|
||||||
const filtered = computed(
|
const filtered = computed(
|
||||||
|
@ -294,9 +296,11 @@ export default defineComponent<FilterDropdownProps<any>>({
|
||||||
|
|
||||||
let filterIcon;
|
let filterIcon;
|
||||||
if (typeof column.filterIcon === 'function') {
|
if (typeof column.filterIcon === 'function') {
|
||||||
filterIcon = column.filterIcon(filtered.value);
|
filterIcon = column.filterIcon({ filtered: filtered.value, column });
|
||||||
} else if (column.filterIcon) {
|
} else if (column.filterIcon) {
|
||||||
filterIcon = column.filterIcon;
|
filterIcon = column.filterIcon;
|
||||||
|
} else if (contextSlots.value.customFilterIcon) {
|
||||||
|
filterIcon = contextSlots.value.customFilterIcon({ filtered: filtered.value, column });
|
||||||
} else {
|
} else {
|
||||||
filterIcon = <FilterFilled />;
|
filterIcon = <FilterFilled />;
|
||||||
}
|
}
|
||||||
|
|
|
@ -143,6 +143,7 @@ function generateFilterInfo<RecordType>(filterStates: FilterState<RecordType>[])
|
||||||
const currentFilters: Record<string, FilterValue | null> = {};
|
const currentFilters: Record<string, FilterValue | null> = {};
|
||||||
|
|
||||||
filterStates.forEach(({ key, filteredKeys, column }) => {
|
filterStates.forEach(({ key, filteredKeys, column }) => {
|
||||||
|
console.log(column);
|
||||||
const { filters, filterDropdown } = column;
|
const { filters, filterDropdown } = column;
|
||||||
if (filterDropdown) {
|
if (filterDropdown) {
|
||||||
currentFilters[key] = filteredKeys || null;
|
currentFilters[key] = filteredKeys || null;
|
||||||
|
|
|
@ -41,6 +41,7 @@ export default function useLazyKVMap<RecordType>(
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
deep: false,
|
deep: false,
|
||||||
|
immediate: true,
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
function getRecordByKey(key: Key): RecordType {
|
function getRecordByKey(key: Key): RecordType {
|
||||||
|
|
|
@ -81,17 +81,19 @@ export default function useSelection<RecordType>(
|
||||||
): [TransformColumns<RecordType>, Ref<Set<Key>>] {
|
): [TransformColumns<RecordType>, Ref<Set<Key>>] {
|
||||||
// ======================== Caches ========================
|
// ======================== Caches ========================
|
||||||
const preserveRecordsRef = ref(new Map<Key, RecordType>());
|
const preserveRecordsRef = ref(new Map<Key, RecordType>());
|
||||||
|
const mergedRowSelection = computed(() => rowSelectionRef.value || {});
|
||||||
// ========================= Keys =========================
|
// ========================= Keys =========================
|
||||||
const [mergedSelectedKeys, setMergedSelectedKeys] = useMergedState(
|
const [mergedSelectedKeys, setMergedSelectedKeys] = useMergedState(
|
||||||
rowSelectionRef.value.selectedRowKeys || rowSelectionRef.value.defaultSelectedRowKeys || [],
|
mergedRowSelection.value.selectedRowKeys ||
|
||||||
|
mergedRowSelection.value.defaultSelectedRowKeys ||
|
||||||
|
[],
|
||||||
{
|
{
|
||||||
value: computed(() => rowSelectionRef.value.selectedRowKeys),
|
value: computed(() => mergedRowSelection.value.selectedRowKeys),
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
const keyEntities = computed(() =>
|
const keyEntities = computed(() =>
|
||||||
rowSelectionRef.value.checkStrictly
|
mergedRowSelection.value.checkStrictly
|
||||||
? { keyEntities: null }
|
? { keyEntities: null }
|
||||||
: convertDataToEntities(configRef.data.value as unknown as DataNode[], {
|
: convertDataToEntities(configRef.data.value as unknown as DataNode[], {
|
||||||
externalGetKey: configRef.getRowKey.value as any,
|
externalGetKey: configRef.getRowKey.value as any,
|
||||||
|
@ -108,7 +110,7 @@ export default function useSelection<RecordType>(
|
||||||
const checkboxPropsMap = computed(() => {
|
const checkboxPropsMap = computed(() => {
|
||||||
const map = new Map<Key, Partial<CheckboxProps>>();
|
const map = new Map<Key, Partial<CheckboxProps>>();
|
||||||
const getRowKey = configRef.getRowKey.value;
|
const getRowKey = configRef.getRowKey.value;
|
||||||
const getCheckboxProps = rowSelectionRef.value.getCheckboxProps;
|
const getCheckboxProps = mergedRowSelection.value.getCheckboxProps;
|
||||||
flattedData.value.forEach((record, index) => {
|
flattedData.value.forEach((record, index) => {
|
||||||
const key = getRowKey(record, index);
|
const key = getRowKey(record, index);
|
||||||
const checkboxProps = (getCheckboxProps ? getCheckboxProps(record) : null) || {};
|
const checkboxProps = (getCheckboxProps ? getCheckboxProps(record) : null) || {};
|
||||||
|
@ -132,13 +134,13 @@ export default function useSelection<RecordType>(
|
||||||
!!checkboxPropsMap.value.get(configRef.getRowKey.value(r))?.disabled;
|
!!checkboxPropsMap.value.get(configRef.getRowKey.value(r))?.disabled;
|
||||||
|
|
||||||
const selectKeysState = computed(() => {
|
const selectKeysState = computed(() => {
|
||||||
if (rowSelectionRef.value.checkStrictly) {
|
if (mergedRowSelection.value.checkStrictly) {
|
||||||
return [mergedSelectedKeys.value || [], []];
|
return [mergedSelectedKeys.value || [], []];
|
||||||
}
|
}
|
||||||
const { checkedKeys, halfCheckedKeys } = conductCheck(
|
const { checkedKeys, halfCheckedKeys } = conductCheck(
|
||||||
mergedSelectedKeys.value,
|
mergedSelectedKeys.value,
|
||||||
true,
|
true,
|
||||||
keyEntities as any,
|
keyEntities.value,
|
||||||
isCheckboxDisabled as any,
|
isCheckboxDisabled as any,
|
||||||
);
|
);
|
||||||
return [checkedKeys || [], halfCheckedKeys];
|
return [checkedKeys || [], halfCheckedKeys];
|
||||||
|
@ -149,13 +151,13 @@ export default function useSelection<RecordType>(
|
||||||
|
|
||||||
const derivedSelectedKeySet = computed<Set<Key>>(() => {
|
const derivedSelectedKeySet = computed<Set<Key>>(() => {
|
||||||
const keys =
|
const keys =
|
||||||
rowSelectionRef.value.type === 'radio'
|
mergedRowSelection.value.type === 'radio'
|
||||||
? derivedSelectedKeys.value.slice(0, 1)
|
? derivedSelectedKeys.value.slice(0, 1)
|
||||||
: derivedSelectedKeys.value;
|
: derivedSelectedKeys.value;
|
||||||
return new Set(keys);
|
return new Set(keys);
|
||||||
});
|
});
|
||||||
const derivedHalfSelectedKeySet = computed(() =>
|
const derivedHalfSelectedKeySet = computed(() =>
|
||||||
rowSelectionRef.value.type === 'radio' ? new Set() : new Set(derivedHalfSelectedKeys.value),
|
mergedRowSelection.value.type === 'radio' ? new Set() : new Set(derivedHalfSelectedKeys.value),
|
||||||
);
|
);
|
||||||
|
|
||||||
// Save last selected key to enable range selection
|
// Save last selected key to enable range selection
|
||||||
|
@ -171,7 +173,7 @@ export default function useSelection<RecordType>(
|
||||||
const setSelectedKeys = (keys: Key[]) => {
|
const setSelectedKeys = (keys: Key[]) => {
|
||||||
let availableKeys: Key[];
|
let availableKeys: Key[];
|
||||||
let records: RecordType[];
|
let records: RecordType[];
|
||||||
const { preserveSelectedRowKeys, onChange: onSelectionChange } = rowSelectionRef.value || {};
|
const { preserveSelectedRowKeys, onChange: onSelectionChange } = mergedRowSelection.value;
|
||||||
const { getRecordByKey } = configRef;
|
const { getRecordByKey } = configRef;
|
||||||
if (preserveSelectedRowKeys) {
|
if (preserveSelectedRowKeys) {
|
||||||
// Keep key if mark as preserveSelectedRowKeys
|
// Keep key if mark as preserveSelectedRowKeys
|
||||||
|
@ -213,7 +215,7 @@ export default function useSelection<RecordType>(
|
||||||
// ====================== Selections ======================
|
// ====================== Selections ======================
|
||||||
// Trigger single `onSelect` event
|
// Trigger single `onSelect` event
|
||||||
const triggerSingleSelection = (key: Key, selected: boolean, keys: Key[], event: Event) => {
|
const triggerSingleSelection = (key: Key, selected: boolean, keys: Key[], event: Event) => {
|
||||||
const { onSelect } = rowSelectionRef.value || {};
|
const { onSelect } = mergedRowSelection.value;
|
||||||
const { getRecordByKey } = configRef || {};
|
const { getRecordByKey } = configRef || {};
|
||||||
if (onSelect) {
|
if (onSelect) {
|
||||||
const rows = keys.map(k => getRecordByKey(k));
|
const rows = keys.map(k => getRecordByKey(k));
|
||||||
|
@ -224,7 +226,7 @@ export default function useSelection<RecordType>(
|
||||||
};
|
};
|
||||||
|
|
||||||
const mergedSelections = computed(() => {
|
const mergedSelections = computed(() => {
|
||||||
const { onSelectInvert, onSelectNone, selections, hideSelectAll } = rowSelectionRef.value || {};
|
const { onSelectInvert, onSelectNone, selections, hideSelectAll } = mergedRowSelection.value;
|
||||||
|
|
||||||
const { data, pageData, getRowKey, locale: tableLocale } = configRef;
|
const { data, pageData, getRowKey, locale: tableLocale } = configRef;
|
||||||
|
|
||||||
|
@ -300,7 +302,7 @@ export default function useSelection<RecordType>(
|
||||||
renderCell: customizeRenderCell,
|
renderCell: customizeRenderCell,
|
||||||
hideSelectAll,
|
hideSelectAll,
|
||||||
checkStrictly = true,
|
checkStrictly = true,
|
||||||
} = rowSelectionRef.value || {};
|
} = mergedRowSelection.value;
|
||||||
|
|
||||||
const {
|
const {
|
||||||
prefixCls,
|
prefixCls,
|
||||||
|
@ -376,7 +378,7 @@ export default function useSelection<RecordType>(
|
||||||
</Menu>
|
</Menu>
|
||||||
);
|
);
|
||||||
customizeSelections = (
|
customizeSelections = (
|
||||||
<div class={`${prefixCls}-selection-extra`}>
|
<div class={`${prefixCls.value}-selection-extra`}>
|
||||||
<Dropdown overlay={menu} getPopupContainer={getPopupContainer.value}>
|
<Dropdown overlay={menu} getPopupContainer={getPopupContainer.value}>
|
||||||
<span>
|
<span>
|
||||||
<DownOutlined />
|
<DownOutlined />
|
||||||
|
@ -401,7 +403,7 @@ export default function useSelection<RecordType>(
|
||||||
const allDisabledSomeChecked = allDisabled && allDisabledData.some(({ checked }) => checked);
|
const allDisabledSomeChecked = allDisabled && allDisabledData.some(({ checked }) => checked);
|
||||||
|
|
||||||
title = !hideSelectAll && (
|
title = !hideSelectAll && (
|
||||||
<div class={`${prefixCls}-selection`}>
|
<div class={`${prefixCls.value}-selection`}>
|
||||||
<Checkbox
|
<Checkbox
|
||||||
checked={
|
checked={
|
||||||
!allDisabled ? !!flattedDataLength.value && checkedCurrentAll : allDisabledAndChecked
|
!allDisabled ? !!flattedDataLength.value && checkedCurrentAll : allDisabledAndChecked
|
||||||
|
@ -539,7 +541,7 @@ export default function useSelection<RecordType>(
|
||||||
const result = conductCheck(
|
const result = conductCheck(
|
||||||
[...originCheckedKeys, key],
|
[...originCheckedKeys, key],
|
||||||
true,
|
true,
|
||||||
keyEntities as any,
|
keyEntities.value,
|
||||||
isCheckboxDisabled as any,
|
isCheckboxDisabled as any,
|
||||||
);
|
);
|
||||||
const { checkedKeys, halfCheckedKeys } = result;
|
const { checkedKeys, halfCheckedKeys } = result;
|
||||||
|
@ -552,7 +554,7 @@ export default function useSelection<RecordType>(
|
||||||
nextCheckedKeys = conductCheck(
|
nextCheckedKeys = conductCheck(
|
||||||
Array.from(tempKeySet),
|
Array.from(tempKeySet),
|
||||||
{ checked: false, halfCheckedKeys },
|
{ checked: false, halfCheckedKeys },
|
||||||
keyEntities as any,
|
keyEntities.value,
|
||||||
isCheckboxDisabled as any,
|
isCheckboxDisabled as any,
|
||||||
).checkedKeys;
|
).checkedKeys;
|
||||||
}
|
}
|
||||||
|
@ -583,15 +585,15 @@ export default function useSelection<RecordType>(
|
||||||
// Columns
|
// Columns
|
||||||
const selectionColumn = {
|
const selectionColumn = {
|
||||||
width: selectionColWidth,
|
width: selectionColWidth,
|
||||||
className: `${prefixCls}-selection-column`,
|
className: `${prefixCls.value}-selection-column`,
|
||||||
title: rowSelectionRef.value.columnTitle || title,
|
title: mergedRowSelection.value.columnTitle || title,
|
||||||
render: renderSelectionCell,
|
render: renderSelectionCell,
|
||||||
[INTERNAL_COL_DEFINE]: {
|
[INTERNAL_COL_DEFINE]: {
|
||||||
class: `${prefixCls}-selection-col`,
|
class: `${prefixCls.value}-selection-col`,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (expandType.value === 'row' && columns.length && !expandIconColumnIndex) {
|
if (expandType.value === 'row' && columns.length && !expandIconColumnIndex.value) {
|
||||||
const [expandColumn, ...restColumns] = columns;
|
const [expandColumn, ...restColumns] = columns;
|
||||||
const selectionFixed = fixed || getFixedType(restColumns[0]);
|
const selectionFixed = fixed || getFixedType(restColumns[0]);
|
||||||
if (selectionFixed) {
|
if (selectionFixed) {
|
||||||
|
|
|
@ -1,18 +1,28 @@
|
||||||
import type { Ref } from 'vue';
|
import type { Ref } from 'vue';
|
||||||
|
import { ContextSlots } from '../context';
|
||||||
import type { TransformColumns, ColumnTitleProps, ColumnsType } from '../interface';
|
import type { TransformColumns, ColumnTitleProps, ColumnsType } from '../interface';
|
||||||
import { renderColumnTitle } from '../util';
|
import { renderColumnTitle } from '../util';
|
||||||
|
|
||||||
function fillTitle<RecordType>(
|
function fillTitle<RecordType>(
|
||||||
columns: ColumnsType<RecordType>,
|
columns: ColumnsType<RecordType>,
|
||||||
columnTitleProps: ColumnTitleProps<RecordType>,
|
columnTitleProps: ColumnTitleProps<RecordType>,
|
||||||
|
contextColumns: Ref<ContextSlots>,
|
||||||
) {
|
) {
|
||||||
|
const $slots = contextColumns.value;
|
||||||
return columns.map(column => {
|
return columns.map(column => {
|
||||||
const cloneColumn = { ...column };
|
const cloneColumn = { ...column };
|
||||||
|
const { slots = {} } = cloneColumn;
|
||||||
|
|
||||||
cloneColumn.title = renderColumnTitle(column.title, columnTitleProps);
|
Object.keys(slots).forEach(key => {
|
||||||
|
const name = slots[key];
|
||||||
|
if (cloneColumn[key] === undefined && $slots[name]) {
|
||||||
|
cloneColumn[key] = $slots[name];
|
||||||
|
}
|
||||||
|
});
|
||||||
|
cloneColumn.title = renderColumnTitle(cloneColumn.title, columnTitleProps);
|
||||||
|
|
||||||
if ('children' in cloneColumn) {
|
if ('children' in cloneColumn) {
|
||||||
cloneColumn.children = fillTitle(cloneColumn.children, columnTitleProps);
|
cloneColumn.children = fillTitle(cloneColumn.children, columnTitleProps, contextColumns);
|
||||||
}
|
}
|
||||||
|
|
||||||
return cloneColumn;
|
return cloneColumn;
|
||||||
|
@ -21,9 +31,10 @@ function fillTitle<RecordType>(
|
||||||
|
|
||||||
export default function useTitleColumns<RecordType>(
|
export default function useTitleColumns<RecordType>(
|
||||||
columnTitleProps: Ref<ColumnTitleProps<RecordType>>,
|
columnTitleProps: Ref<ColumnTitleProps<RecordType>>,
|
||||||
|
contextColumns: Ref<ContextSlots>,
|
||||||
): [TransformColumns<RecordType>] {
|
): [TransformColumns<RecordType>] {
|
||||||
const filledColumns = (columns: ColumnsType<RecordType>) =>
|
const filledColumns = (columns: ColumnsType<RecordType>) =>
|
||||||
fillTitle(columns, columnTitleProps.value);
|
fillTitle(columns, columnTitleProps.value, contextColumns);
|
||||||
|
|
||||||
return [filledColumns];
|
return [filledColumns];
|
||||||
}
|
}
|
||||||
|
|
|
@ -106,7 +106,7 @@ export interface ColumnType<RecordType = DefaultRecordType> extends RcColumnType
|
||||||
filterMultiple?: boolean;
|
filterMultiple?: boolean;
|
||||||
filteredValue?: FilterValue | null;
|
filteredValue?: FilterValue | null;
|
||||||
defaultFilteredValue?: FilterValue | null;
|
defaultFilteredValue?: FilterValue | null;
|
||||||
filterIcon?: VueNode | ((filtered: boolean) => VueNode);
|
filterIcon?: VueNode | ((opt: { filtered: boolean; column: ColumnType }) => VueNode);
|
||||||
onFilter?: (value: string | number | boolean, record: RecordType) => boolean;
|
onFilter?: (value: string | number | boolean, record: RecordType) => boolean;
|
||||||
filterDropdownVisible?: boolean;
|
filterDropdownVisible?: boolean;
|
||||||
onFilterDropdownVisibleChange?: (visible: boolean) => void;
|
onFilterDropdownVisibleChange?: (visible: boolean) => void;
|
||||||
|
|
|
@ -149,6 +149,7 @@ export default defineComponent<BodyRowProps<unknown>>({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Cell
|
<Cell
|
||||||
|
cellType="body"
|
||||||
class={columnClassName}
|
class={columnClassName}
|
||||||
ellipsis={column.ellipsis}
|
ellipsis={column.ellipsis}
|
||||||
align={column.align}
|
align={column.align}
|
||||||
|
@ -193,7 +194,12 @@ export default defineComponent<BodyRowProps<unknown>>({
|
||||||
// ======================== Expand Row =========================
|
// ======================== Expand Row =========================
|
||||||
let expandRowNode;
|
let expandRowNode;
|
||||||
if (rowSupportExpand.value && (expandRended.value || expanded.value)) {
|
if (rowSupportExpand.value && (expandRended.value || expanded.value)) {
|
||||||
const expandContent = expandedRowRender(record, index, indent + 1, expanded.value);
|
const expandContent = expandedRowRender({
|
||||||
|
record,
|
||||||
|
index,
|
||||||
|
indent: indent + 1,
|
||||||
|
expanded: expanded.value,
|
||||||
|
});
|
||||||
const computedExpandedRowClassName =
|
const computedExpandedRowClassName =
|
||||||
expandedRowClassName && expandedRowClassName(record, index, indent);
|
expandedRowClassName && expandedRowClassName(record, index, indent);
|
||||||
expandRowNode = (
|
expandRowNode = (
|
||||||
|
|
|
@ -14,6 +14,7 @@ import type {
|
||||||
CellEllipsisType,
|
CellEllipsisType,
|
||||||
} from '../interface';
|
} from '../interface';
|
||||||
import { getPathValue, validateValue } from '../utils/valueUtil';
|
import { getPathValue, validateValue } from '../utils/valueUtil';
|
||||||
|
import { useInjectSlots } from '../../table/context';
|
||||||
|
|
||||||
function isRenderCell<RecordType = DefaultRecordType>(
|
function isRenderCell<RecordType = DefaultRecordType>(
|
||||||
data: RenderedCell<RecordType>,
|
data: RenderedCell<RecordType>,
|
||||||
|
@ -53,6 +54,8 @@ export interface CellProps<RecordType = DefaultRecordType> {
|
||||||
isSticky?: boolean;
|
isSticky?: boolean;
|
||||||
|
|
||||||
column?: ColumnType<RecordType>;
|
column?: ColumnType<RecordType>;
|
||||||
|
|
||||||
|
cellType?: 'header' | 'body';
|
||||||
}
|
}
|
||||||
export default defineComponent<CellProps>({
|
export default defineComponent<CellProps>({
|
||||||
name: 'Cell',
|
name: 'Cell',
|
||||||
|
@ -62,7 +65,6 @@ export default defineComponent<CellProps>({
|
||||||
'index',
|
'index',
|
||||||
'dataIndex',
|
'dataIndex',
|
||||||
'customRender',
|
'customRender',
|
||||||
'children',
|
|
||||||
'component',
|
'component',
|
||||||
'colSpan',
|
'colSpan',
|
||||||
'rowSpan',
|
'rowSpan',
|
||||||
|
@ -79,9 +81,11 @@ export default defineComponent<CellProps>({
|
||||||
'rowType',
|
'rowType',
|
||||||
'isSticky',
|
'isSticky',
|
||||||
'column',
|
'column',
|
||||||
|
'cellType',
|
||||||
] as any,
|
] as any,
|
||||||
slots: ['appendNode'],
|
slots: ['appendNode'],
|
||||||
setup(props, { slots }) {
|
setup(props, { slots }) {
|
||||||
|
const contextSlots = useInjectSlots();
|
||||||
return () => {
|
return () => {
|
||||||
const {
|
const {
|
||||||
prefixCls,
|
prefixCls,
|
||||||
|
@ -105,6 +109,7 @@ export default defineComponent<CellProps>({
|
||||||
rowType,
|
rowType,
|
||||||
isSticky,
|
isSticky,
|
||||||
column,
|
column,
|
||||||
|
cellType,
|
||||||
} = props;
|
} = props;
|
||||||
const cellPrefixCls = `${prefixCls}-cell`;
|
const cellPrefixCls = `${prefixCls}-cell`;
|
||||||
|
|
||||||
|
@ -112,8 +117,11 @@ export default defineComponent<CellProps>({
|
||||||
let cellProps: CellType;
|
let cellProps: CellType;
|
||||||
let childNode;
|
let childNode;
|
||||||
const children = slots.default?.();
|
const children = slots.default?.();
|
||||||
if (validateValue(children)) {
|
if (validateValue(children) || cellType === 'header') {
|
||||||
childNode = children;
|
childNode = children;
|
||||||
|
if (cellType === 'header' && contextSlots.value.headerCell) {
|
||||||
|
childNode = contextSlots.value.headerCell({ title: column.title, index, column });
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
const value = getPathValue(record, dataIndex);
|
const value = getPathValue(record, dataIndex);
|
||||||
|
|
||||||
|
@ -129,6 +137,10 @@ export default defineComponent<CellProps>({
|
||||||
childNode = renderData;
|
childNode = renderData;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (cellType === 'body' && contextSlots.value.bodyCell) {
|
||||||
|
childNode = contextSlots.value.bodyCell({ text: value, value, record, index, column });
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not crash if final `childNode` is not validate ReactNode
|
// Not crash if final `childNode` is not validate ReactNode
|
||||||
|
|
|
@ -92,6 +92,7 @@ export interface HeaderProps<RecordType = DefaultRecordType> {
|
||||||
|
|
||||||
export default defineComponent<HeaderProps>({
|
export default defineComponent<HeaderProps>({
|
||||||
name: 'Header',
|
name: 'Header',
|
||||||
|
inheritAttrs: false,
|
||||||
props: ['columns', 'flattenColumns', 'stickyOffsets', 'customHeaderRow'] as any,
|
props: ['columns', 'flattenColumns', 'stickyOffsets', 'customHeaderRow'] as any,
|
||||||
setup(props) {
|
setup(props) {
|
||||||
const tableContext = useInjectTable();
|
const tableContext = useInjectTable();
|
||||||
|
|
|
@ -77,6 +77,7 @@ export default defineComponent<RowProps>({
|
||||||
return (
|
return (
|
||||||
<Cell
|
<Cell
|
||||||
{...cell}
|
{...cell}
|
||||||
|
cellType="header"
|
||||||
ellipsis={column.ellipsis}
|
ellipsis={column.ellipsis}
|
||||||
align={column.align}
|
align={column.align}
|
||||||
component={CellComponent}
|
component={CellComponent}
|
||||||
|
|
|
@ -54,6 +54,7 @@ import VCResizeObserver from '../vc-resize-observer';
|
||||||
import { useProvideTable } from './context/TableContext';
|
import { useProvideTable } from './context/TableContext';
|
||||||
import { useProvideBody } from './context/BodyContext';
|
import { useProvideBody } from './context/BodyContext';
|
||||||
import { useProvideResize } from './context/ResizeContext';
|
import { useProvideResize } from './context/ResizeContext';
|
||||||
|
import { getDataAndAriaProps } from './utils/legacyUtil';
|
||||||
|
|
||||||
// Used for conditions cache
|
// Used for conditions cache
|
||||||
const EMPTY_DATA = [];
|
const EMPTY_DATA = [];
|
||||||
|
@ -178,7 +179,8 @@ export default defineComponent<TableProps>({
|
||||||
'internalRefs',
|
'internalRefs',
|
||||||
'canExpandable',
|
'canExpandable',
|
||||||
] as any,
|
] as any,
|
||||||
setup(props, { slots, emit }) {
|
inheritAttrs: false,
|
||||||
|
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);
|
||||||
|
|
||||||
|
@ -749,9 +751,10 @@ export default defineComponent<TableProps>({
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
const ariaProps = getDataAndAriaProps(attrs);
|
||||||
let fullTable = (
|
let fullTable = (
|
||||||
<div
|
<div
|
||||||
|
{...ariaProps}
|
||||||
class={classNames(prefixCls, {
|
class={classNames(prefixCls, {
|
||||||
[`${prefixCls}-rtl`]: direction === 'rtl',
|
[`${prefixCls}-rtl`]: direction === 'rtl',
|
||||||
[`${prefixCls}-ping-left`]: pingedLeft.value,
|
[`${prefixCls}-ping-left`]: pingedLeft.value,
|
||||||
|
@ -765,7 +768,9 @@ export default defineComponent<TableProps>({
|
||||||
[`${prefixCls}-has-fix-right`]:
|
[`${prefixCls}-has-fix-right`]:
|
||||||
flattenColumns.value[columnCount.value - 1] &&
|
flattenColumns.value[columnCount.value - 1] &&
|
||||||
flattenColumns.value[columnCount.value - 1].fixed === 'right',
|
flattenColumns.value[columnCount.value - 1].fixed === 'right',
|
||||||
|
[attrs.class as string]: attrs.class,
|
||||||
})}
|
})}
|
||||||
|
style={attrs.style}
|
||||||
id={id}
|
id={id}
|
||||||
ref={fullTableRef}
|
ref={fullTableRef}
|
||||||
>
|
>
|
||||||
|
|
|
@ -20,12 +20,12 @@ export interface TableContextProps {
|
||||||
summaryCollect: (uniKey: string, fixed: boolean | string) => void;
|
summaryCollect: (uniKey: string, fixed: boolean | string) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const BodyContextKey: InjectionKey<TableContextProps> = Symbol('TableContextProps');
|
export const TableContextKey: InjectionKey<TableContextProps> = Symbol('TableContextProps');
|
||||||
|
|
||||||
export const useProvideTable = (props: TableContextProps) => {
|
export const useProvideTable = (props: TableContextProps) => {
|
||||||
provide(BodyContextKey, props);
|
provide(TableContextKey, props);
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useInjectTable = () => {
|
export const useInjectTable = () => {
|
||||||
return inject(BodyContextKey, {} as TableContextProps);
|
return inject(TableContextKey, {} as TableContextProps);
|
||||||
};
|
};
|
||||||
|
|
|
@ -66,6 +66,14 @@ interface ColumnSharedType<RecordType> {
|
||||||
customHeaderCell?: GetComponentProps<ColumnsType<RecordType>[number]>;
|
customHeaderCell?: GetComponentProps<ColumnsType<RecordType>[number]>;
|
||||||
ellipsis?: CellEllipsisType;
|
ellipsis?: CellEllipsisType;
|
||||||
align?: AlignType;
|
align?: AlignType;
|
||||||
|
|
||||||
|
/** @deprecated Please use `v-slot:filterIcon` `v-slot:bodyCell` `v-slot:headerCell` instead */
|
||||||
|
slots?: {
|
||||||
|
filterIcon?: string;
|
||||||
|
filterDropdown?: string;
|
||||||
|
customRender?: string;
|
||||||
|
title?: string;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ColumnGroupType<RecordType> extends ColumnSharedType<RecordType> {
|
export interface ColumnGroupType<RecordType> extends ColumnSharedType<RecordType> {
|
||||||
|
@ -176,12 +184,12 @@ export interface LegacyExpandableProps<RecordType> {
|
||||||
rowExpandable?: (record: RecordType) => boolean;
|
rowExpandable?: (record: RecordType) => boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ExpandedRowRender<ValueType> = (
|
export type ExpandedRowRender<ValueType> = (opt: {
|
||||||
record: ValueType,
|
record: ValueType;
|
||||||
index: number,
|
index: number;
|
||||||
indent: number,
|
indent: number;
|
||||||
expanded: boolean,
|
expanded: boolean;
|
||||||
) => any;
|
}) => any;
|
||||||
|
|
||||||
export interface RenderExpandIconProps<RecordType> {
|
export interface RenderExpandIconProps<RecordType> {
|
||||||
prefixCls: string;
|
prefixCls: string;
|
||||||
|
|
|
@ -421,8 +421,8 @@ export default defineComponent({
|
||||||
let titleNode: any;
|
let titleNode: any;
|
||||||
if (typeof title === 'function') {
|
if (typeof title === 'function') {
|
||||||
titleNode = title(renderArgsData.value);
|
titleNode = title(renderArgsData.value);
|
||||||
} else if (contextSlots.titleRender) {
|
} else if (contextSlots.valuetitleRender) {
|
||||||
titleNode = contextSlots.titleRender(renderArgsData.value);
|
titleNode = contextSlots.valuetitleRender(renderArgsData.value);
|
||||||
} else {
|
} else {
|
||||||
titleNode = title;
|
titleNode = title;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,5 @@
|
||||||
<template>
|
<template>
|
||||||
<a-table :columns="columns" :data-source="data">
|
<a-table :columns="columns" :data-source="data">
|
||||||
<template #name="{ text }">
|
|
||||||
<a>{{ text }}</a>
|
|
||||||
</template>
|
|
||||||
<template #customTitle>
|
<template #customTitle>
|
||||||
<span>
|
<span>
|
||||||
<smile-outlined />
|
<smile-outlined />
|
||||||
|
@ -36,9 +33,10 @@
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { SmileOutlined, DownOutlined } from '@ant-design/icons-vue';
|
import { SmileOutlined, DownOutlined } from '@ant-design/icons-vue';
|
||||||
import { defineComponent } from 'vue';
|
import { defineComponent, ref } from 'vue';
|
||||||
const columns = [
|
const columns = [
|
||||||
{
|
{
|
||||||
|
title: 'Name',
|
||||||
dataIndex: 'name',
|
dataIndex: 'name',
|
||||||
key: 'name',
|
key: 'name',
|
||||||
slots: { title: 'customTitle', customRender: 'name' },
|
slots: { title: 'customTitle', customRender: 'name' },
|
||||||
|
@ -96,9 +94,12 @@ export default defineComponent({
|
||||||
DownOutlined,
|
DownOutlined,
|
||||||
},
|
},
|
||||||
setup() {
|
setup() {
|
||||||
|
const test = ref('111');
|
||||||
|
window.test = test;
|
||||||
return {
|
return {
|
||||||
data,
|
data,
|
||||||
columns,
|
columns,
|
||||||
|
test,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in New Issue