wip(table): perf table

This commit is contained in:
vben 2020-12-28 23:33:23 +08:00
parent a305e59124
commit 3549043f37
24 changed files with 520 additions and 387 deletions

View File

@ -12,10 +12,13 @@
- form: 新增远程下拉`ApiSelect`及示例 - form: 新增远程下拉`ApiSelect`及示例
- form: 新增`autoFocusFirstItem`配置。用于配置是否聚焦表单第一个输入框 - form: 新增`autoFocusFirstItem`配置。用于配置是否聚焦表单第一个输入框
- useForm: 支持动态改变参数。可以传入`Ref`类型与`Computed`类型进行动态更改 - useForm: 支持动态改变参数。可以传入`Ref`类型与`Computed`类型进行动态更改
- table: 新增`clickToRowSelect`属性。用于控制点击行是否选中勾选狂
- table: 监听行点击事件
### ⚡ Performance Improvements ### ⚡ Performance Improvements
- 优化`modal`与`drawer`滚动条组件 - 优化`modal`与`drawer`滚动条组件
- table: 移除 `isTreeTable`属性
### 🎫 Chores ### 🎫 Chores

View File

@ -225,6 +225,10 @@
padding: 16px !important; padding: 16px !important;
margin-bottom: 0 !important; margin-bottom: 0 !important;
} }
> .scrollbar > .scrollbar__bar.is-horizontal {
display: none;
}
} }
} }

View File

@ -43,7 +43,7 @@
if (el) { if (el) {
await nextTick(); await nextTick();
const icon = unref(getIconRef); const icon = unref(getIconRef);
if (!icon) return;
const svg = Iconify.renderSVG(icon, {}); const svg = Iconify.renderSVG(icon, {});
if (svg) { if (svg) {
@ -74,7 +74,7 @@
} }
); );
watch(() => props.icon, update, { flush: 'post' }); // watch(() => props.icon, update, { flush: 'post' });
onMounted(update); onMounted(update);

View File

@ -40,6 +40,10 @@
.ant-modal-body { .ant-modal-body {
padding: 0; padding: 0;
> .scrollbar > .scrollbar__bar.is-horizontal {
display: none;
}
} }
&-large { &-large {

View File

@ -11,7 +11,7 @@
:submitOnReset="true" :submitOnReset="true"
v-bind="getFormProps" v-bind="getFormProps"
v-if="getBindValues.useSearchForm" v-if="getBindValues.useSearchForm"
:submitButtonOptions="{ loading }" :submitButtonOptions="{ loading: getLoading }"
:tableAction="tableAction" :tableAction="tableAction"
@register="registerForm" @register="registerForm"
@submit="handleSearchInfoChange" @submit="handleSearchInfoChange"
@ -35,18 +35,10 @@
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts">
import type { import type { BasicTableProps, TableActionType, SizeType, SorterResult } from './types/table';
BasicTableProps,
FetchParams,
GetColumnsParams,
TableActionType,
SizeType,
SorterResult,
TableCustomRecord,
} from './types/table';
import { PaginationProps } from './types/pagination'; import { PaginationProps } from './types/pagination';
import { defineComponent, ref, computed, unref, watch, nextTick, toRaw } from 'vue'; import { defineComponent, ref, computed, unref, watch, nextTick } from 'vue';
import { Table } from 'ant-design-vue'; import { Table } from 'ant-design-vue';
import renderTitle from './components/renderTitle'; import renderTitle from './components/renderTitle';
import renderFooter from './components/renderFooter'; import renderFooter from './components/renderFooter';
@ -64,51 +56,64 @@
import { useRowSelection } from './hooks/useRowSelection'; import { useRowSelection } from './hooks/useRowSelection';
import { useTableScroll } from './hooks/useTableScroll'; import { useTableScroll } from './hooks/useTableScroll';
import { provideTable } from './hooks/useProvinceTable'; import { provideTable } from './hooks/useProvinceTable';
import { useCustomRow } from './hooks/useCustomRow';
import { useTableStyle } from './hooks/useTableStyle';
import { useEventListener } from '/@/hooks/event/useEventListener'; import { useEventListener } from '/@/hooks/event/useEventListener';
import { basicProps } from './props'; import { basicProps } from './props';
import { ROW_KEY } from './const';
import { useExpose } from '/@/hooks/core/useExpose'; import { useExpose } from '/@/hooks/core/useExpose';
import './style/index.less'; import './style/index.less';
export default defineComponent({ export default defineComponent({
props: basicProps, props: basicProps,
components: { Table, BasicForm }, components: { Table, BasicForm },
emits: ['fetch-success', 'fetch-error', 'selection-change', 'register'], emits: [
'fetch-success',
'fetch-error',
'selection-change',
'register',
'row-click',
'row-dbClick',
'row-contextmenu',
'row-mouseenter',
'row-mouseleave',
],
setup(props, { attrs, emit, slots }) { setup(props, { attrs, emit, slots }) {
const tableElRef = ref<ComponentRef>(null); const tableElRef = ref<ComponentRef>(null);
const wrapRef = ref<Nullable<HTMLDivElement>>(null); const wrapRef = ref<Nullable<HTMLDivElement>>(null);
const innerPropsRef = ref<Partial<BasicTableProps>>(); const innerPropsRef = ref<Partial<BasicTableProps>>();
const [registerForm, { getFieldsValue }] = useForm(); const [registerForm, { getFieldsValue }] = useForm();
const getMergeProps = computed(() => { const getProps = computed(() => {
return { return { ...props, ...unref(innerPropsRef) } as BasicTableProps;
...props,
...unref(innerPropsRef),
} as BasicTableProps;
}); });
// const getProps = computed( const { getLoading, setLoading } = useLoading(getProps);
// (): FormProps => { const { getPaginationInfo, getPagination, setPagination } = usePagination(getProps);
// return deepMerge(toRaw(props), unref(innerPropsRef)); const { getColumnsRef, getColumns, setColumns } = useColumns(getProps, getPaginationInfo);
// } const {
// ); getDataSourceRef,
getDataSource,
const { loadingRef } = useLoading(getMergeProps); setTableData,
const { getPaginationRef, setPagination } = usePagination(getMergeProps); fetch,
const { getColumnsRef, setColumns } = useColumns(getMergeProps, getPaginationRef); getRowKey,
const { getDataSourceRef, setTableData, fetch, getAutoCreateKey } = useDataSource( reload,
getMergeProps, getAutoCreateKey,
} = useDataSource(
getProps,
{ {
getPaginationRef, getPaginationInfo,
loadingRef, setLoading,
setPagination, setPagination,
getFieldsValue, getFieldsValue,
}, },
emit emit
); );
const { getScrollRef, redoHeight } = useTableScroll(getMergeProps, tableElRef); const { getScrollRef, redoHeight } = useTableScroll(getProps, tableElRef);
const { const {
getRowSelectionRef, getRowSelectionRef,
getSelectRows, getSelectRows,
@ -116,55 +121,58 @@
getSelectRowKeys, getSelectRowKeys,
deleteSelectRowByKey, deleteSelectRowByKey,
setSelectedRowKeys, setSelectedRowKeys,
} = useRowSelection(getMergeProps, emit); } = useRowSelection(getProps, emit);
const getRowKey = computed(() => { const { customRow } = useCustomRow(getProps, {
const { rowKey } = unref(getMergeProps); setSelectedRowKeys,
getSelectRowKeys,
return unref(getAutoCreateKey) ? ROW_KEY : rowKey; clearSelectedRowKeys,
getAutoCreateKey,
emit,
}); });
const { getRowClassName } = useTableStyle(getProps);
const getTitleProps = computed(
(): Recordable => {
const { title, showTableSetting, titleHelpMessage, tableSetting } = unref(getProps);
const hideTitle = !slots.tableTitle && !title && !slots.toolbar && !showTableSetting;
if (hideTitle && !isString(title)) {
return {};
}
return {
title: hideTitle
? null
: renderTitle.bind(
null,
title,
titleHelpMessage,
slots,
showTableSetting,
tableSetting
),
};
}
);
const getBindValues = computed(() => { const getBindValues = computed(() => {
const { title, titleHelpMessage, showSummary, showTableSetting, tableSetting } = unref( const { showSummary } = unref(getProps);
getMergeProps
); let propsData: Recordable = {
const hideTitle = !slots.tableTitle && !title && !slots.toolbar && !showTableSetting;
const titleData: Recordable =
hideTitle && !isString(title)
? {}
: {
title: hideTitle
? null
: renderTitle.bind(
null,
title,
titleHelpMessage,
slots,
showTableSetting,
tableSetting
),
};
const pagination = unref(getPaginationRef);
const rowSelection = unref(getRowSelectionRef);
const scroll = unref(getScrollRef);
const loading = unref(loadingRef);
const rowKey = unref(getRowKey);
const columns = unref(getColumnsRef);
const dataSource = unref(getDataSourceRef);
let propsData = {
size: 'middle', size: 'middle',
...(slots.expandedRowRender ? { expandIcon: renderExpandIcon() } : {}), ...(slots.expandedRowRender ? { expandIcon: renderExpandIcon() } : {}),
...attrs, ...attrs,
...unref(getMergeProps), customRow,
...titleData, ...unref(getProps),
scroll, ...unref(getTitleProps),
loading, scroll: unref(getScrollRef),
loading: unref(getLoading),
tableLayout: 'fixed', tableLayout: 'fixed',
rowSelection, rowSelection: unref(getRowSelectionRef),
rowKey, rowKey: unref(getRowKey),
columns, columns: unref(getColumnsRef),
pagination, pagination: unref(getPaginationInfo),
dataSource, dataSource: unref(getDataSourceRef),
}; };
if (slots.expandedRowRender) { if (slots.expandedRowRender) {
propsData = omit(propsData, 'scroll'); propsData = omit(propsData, 'scroll');
@ -173,7 +181,7 @@
propsData.footer = renderFooter.bind(null, { propsData.footer = renderFooter.bind(null, {
scroll: scroll as any, scroll: scroll as any,
columnsRef: getColumnsRef, columnsRef: getColumnsRef,
summaryFunc: unref(getMergeProps).summaryFunc, summaryFunc: unref(getProps).summaryFunc,
dataSourceRef: getDataSourceRef, dataSourceRef: getDataSourceRef,
rowSelectionRef: getRowSelectionRef, rowSelectionRef: getRowSelectionRef,
}); });
@ -182,17 +190,17 @@
}); });
const getFormProps = computed(() => { const getFormProps = computed(() => {
const { formConfig } = unref(getBindValues); const { formConfig } = unref(getProps);
const formProps: FormProps = { const formProps: Partial<FormProps> = {
showAdvancedButton: true, showAdvancedButton: true,
...(formConfig as FormProps), ...formConfig,
compact: true, compact: true,
}; };
return formProps; return formProps;
}); });
const getEmptyDataIsShowTable = computed(() => { const getEmptyDataIsShowTable = computed(() => {
const { emptyDataIsShowTable, useSearchForm } = unref(getMergeProps); const { emptyDataIsShowTable, useSearchForm } = unref(getProps);
if (emptyDataIsShowTable || !useSearchForm) { if (emptyDataIsShowTable || !useSearchForm) {
return true; return true;
} }
@ -207,17 +215,8 @@
{ immediate: true } { immediate: true }
); );
function getRowClassName(record: TableCustomRecord, index: number) {
const { striped, rowClassName } = unref(getMergeProps);
if (!striped) return;
if (rowClassName && isFunction(rowClassName)) {
return rowClassName(record);
}
return (index || 0) % 2 === 1 ? 'basic-table-row__striped' : '';
}
function handleSearchInfoChange(info: any) { function handleSearchInfoChange(info: any) {
const { handleSearchInfoFn } = unref(getMergeProps); const { handleSearchInfoFn } = unref(getProps);
if (handleSearchInfoFn && isFunction(handleSearchInfoFn)) { if (handleSearchInfoFn && isFunction(handleSearchInfoFn)) {
info = handleSearchInfoFn(info) || info; info = handleSearchInfoFn(info) || info;
} }
@ -230,7 +229,7 @@
filters: Partial<Recordable<string[]>>, filters: Partial<Recordable<string[]>>,
sorter: SorterResult sorter: SorterResult
) { ) {
const { clearSelectOnPageChange, sortFn } = unref(getMergeProps); const { clearSelectOnPageChange, sortFn } = unref(getProps);
if (clearSelectOnPageChange) { if (clearSelectOnPageChange) {
clearSelectedRowKeys(); clearSelectedRowKeys();
} }
@ -245,7 +244,7 @@
} }
function handleSummary() { function handleSummary() {
if (unref(getMergeProps).showSummary) { if (unref(getProps).showSummary) {
nextTick(() => { nextTick(() => {
const tableEl = unref(tableElRef); const tableEl = unref(tableElRef);
if (!tableEl) return; if (!tableEl) return;
@ -273,9 +272,7 @@
} }
const tableAction: TableActionType = { const tableAction: TableActionType = {
reload: async (opt?: FetchParams) => { reload,
await fetch(opt);
},
getSelectRows, getSelectRows,
clearSelectedRowKeys, clearSelectedRowKeys,
getSelectRowKeys, getSelectRowKeys,
@ -285,27 +282,11 @@
redoHeight, redoHeight,
setSelectedRowKeys, setSelectedRowKeys,
setColumns, setColumns,
getPaginationRef: () => { setLoading,
return unref(getPaginationRef); getDataSource,
},
getColumns: (opt?: GetColumnsParams) => {
const { ignoreIndex, ignoreAction } = opt || {};
let columns = toRaw(unref(getColumnsRef));
if (ignoreIndex) {
columns = columns.filter((item) => item.flag !== 'INDEX');
}
if (ignoreAction) {
columns = columns.filter((item) => item.flag !== 'ACTION');
}
return columns;
},
getDataSource: () => {
return unref(getDataSourceRef);
},
setLoading: (loading: boolean) => {
loadingRef.value = loading;
},
setProps, setProps,
getPaginationRef: getPagination,
getColumns,
getSize: () => { getSize: () => {
return unref(getBindValues).size as SizeType; return unref(getBindValues).size as SizeType;
}, },
@ -323,7 +304,7 @@
return { return {
tableElRef, tableElRef,
getBindValues, getBindValues,
loading: loadingRef, getLoading,
registerForm, registerForm,
handleSearchInfoChange, handleSearchInfoChange,
getFormProps, getFormProps,

View File

@ -31,3 +31,9 @@ export function DEFAULT_SORT_FN(sortInfo: SorterResult) {
order, order,
}; };
} }
// 表格单元格默认布局
export const DEFAULT_ALIGN = 'center';
export const INDEX_COLUMN_FLAG = 'INDEX';
export const ACTION_COLUMN_FLAG = 'ACTION';

View File

@ -1,113 +1,133 @@
import { BasicColumn, BasicTableProps } from '../types/table'; import { BasicColumn, BasicTableProps, GetColumnsParams } from '../types/table';
import { PaginationProps } from '../types/pagination'; import { PaginationProps } from '../types/pagination';
import { unref, ComputedRef, Ref, computed, watchEffect, ref, toRaw } from 'vue'; import { unref, ComputedRef, Ref, computed, watchEffect, ref, toRaw } from 'vue';
import { isBoolean, isArray, isObject } from '/@/utils/is'; import { isBoolean, isArray, isObject } from '/@/utils/is';
import { PAGE_SIZE } from '../const'; import { DEFAULT_ALIGN, PAGE_SIZE, INDEX_COLUMN_FLAG, ACTION_COLUMN_FLAG } from '../const';
import { useProps } from './useProps';
import { useI18n } from '/@/hooks/web/useI18n'; import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n(); const { t } = useI18n();
export function useColumns(
refProps: ComputedRef<BasicTableProps>, function handleItem(item: BasicColumn, ellipsis: boolean) {
getPaginationRef: ComputedRef<false | PaginationProps> const { key, dataIndex, children } = item;
item.align = item.align || DEFAULT_ALIGN;
if (ellipsis) {
if (!key) {
item.key = dataIndex;
}
if (!isBoolean(item.ellipsis)) {
Object.assign(item, {
ellipsis,
});
}
}
if (children && children.length) {
handleChildren(children, !!ellipsis);
}
}
function handleChildren(children: BasicColumn[] | undefined, ellipsis: boolean) {
if (!children) return;
children.forEach((item) => {
const { children } = item;
handleItem(item, ellipsis);
handleChildren(children, ellipsis);
});
}
function handleIndexColumn(
propsRef: ComputedRef<BasicTableProps>,
getPaginationRef: ComputedRef<boolean | PaginationProps>,
columns: BasicColumn[]
) {
const { showIndexColumn, indexColumnProps, ellipsis } = unref(propsRef);
let pushIndexColumns = false;
columns.forEach((item) => {
const { children } = item;
handleItem(item, !!ellipsis);
const isTreeTable = children && children.length;
const indIndex = columns.findIndex((column) => column.flag === INDEX_COLUMN_FLAG);
if (showIndexColumn && !isTreeTable) {
pushIndexColumns = indIndex === -1;
} else if (!showIndexColumn && !isTreeTable && indIndex !== -1) {
columns.splice(indIndex, 1);
}
});
if (!pushIndexColumns) return;
const isFixedLeft = columns.some((item) => item.fixed === 'left');
columns.unshift({
flag: INDEX_COLUMN_FLAG,
width: 50,
title: t('component.table.index'),
align: 'center',
customRender: ({ index }) => {
const getPagination = unref(getPaginationRef);
if (isBoolean(getPagination)) {
return `${index + 1}`;
}
const { current = 1, pageSize = PAGE_SIZE } = getPagination;
const currentIndex = (current - 1) * pageSize + index + 1;
return currentIndex;
},
...(isFixedLeft
? {
fixed: 'left',
}
: {}),
...indexColumnProps,
});
}
function handleActionColumn(propsRef: ComputedRef<BasicTableProps>, columns: BasicColumn[]) {
const { actionColumn } = unref(propsRef);
if (!actionColumn) return;
const hasIndex = columns.findIndex((column) => column.flag === ACTION_COLUMN_FLAG);
if (hasIndex === -1) {
columns.push({
...columns[hasIndex],
fixed: 'right',
...actionColumn,
flag: ACTION_COLUMN_FLAG,
});
}
}
export function useColumns(
propsRef: ComputedRef<BasicTableProps>,
getPaginationRef: ComputedRef<boolean | PaginationProps>
) { ) {
const { propsRef } = useProps(refProps);
const columnsRef = (ref(unref(propsRef).columns) as unknown) as Ref<BasicColumn[]>; const columnsRef = (ref(unref(propsRef).columns) as unknown) as Ref<BasicColumn[]>;
const cacheColumnsRef = (ref(unref(propsRef).columns) as unknown) as Ref<BasicColumn[]>; let cacheColumns = unref(propsRef).columns;
const getColumnsRef = computed(() => { const getColumnsRef = computed(() => {
const props = unref(propsRef);
const { showIndexColumn, indexColumnProps, ellipsis, actionColumn, isTreeTable } = props;
const columns = unref(columnsRef); const columns = unref(columnsRef);
if (!columns) { if (!columns) {
return []; return [];
} }
let pushIndexColumns = false;
columns.forEach((item) => {
const { children } = item;
handleItem(item, !!ellipsis);
handleChildren(children, !!ellipsis); handleIndexColumn(propsRef, getPaginationRef, columns);
handleActionColumn(propsRef, columns);
const indIndex = columns.findIndex((column) => column.flag === 'INDEX');
if (showIndexColumn && !isTreeTable) {
pushIndexColumns = indIndex === -1;
} else if (!showIndexColumn && !isTreeTable && indIndex !== -1) {
columns.splice(indIndex, 1);
}
});
if (pushIndexColumns) {
const isFixedLeft = columns.some((item) => item.fixed === 'left');
columns.unshift({
flag: 'INDEX',
width: 50,
title: t('component.table.index'),
align: 'center',
customRender: ({ index }) => {
const getPagination = unref(getPaginationRef);
if (isBoolean(getPagination)) {
return `${index + 1}`;
}
const { current = 1, pageSize = PAGE_SIZE } = getPagination;
const currentIndex = (current - 1) * pageSize + index + 1;
return currentIndex;
},
...(isFixedLeft
? {
fixed: 'left',
}
: {}),
...indexColumnProps,
});
}
if (actionColumn) {
const hasIndex = columns.findIndex((column) => column.flag === 'ACTION');
if (hasIndex === -1) {
columns.push({
...columns[hasIndex],
fixed: 'right',
...actionColumn,
flag: 'ACTION',
});
}
}
return columns; return columns;
}); });
watchEffect(() => { watchEffect(() => {
const columns = toRaw(unref(propsRef).columns); const columns = toRaw(unref(propsRef).columns);
columnsRef.value = columns; columnsRef.value = columns;
cacheColumnsRef.value = columns; cacheColumns = columns;
}); });
function handleItem(item: BasicColumn, ellipsis: boolean) { /**
const { key, dataIndex } = item; * set columns
item.align = item.align || 'center'; * @param columns keycolumn
if (ellipsis) { */
if (!key) { function setColumns(columns: Partial<BasicColumn>[] | string[]) {
item.key = dataIndex;
}
if (!isBoolean(item.ellipsis)) {
Object.assign(item, {
ellipsis,
});
}
}
}
function handleChildren(children: BasicColumn[] | undefined, ellipsis: boolean) {
if (!children) return;
children.forEach((item) => {
const { children } = item;
handleItem(item, ellipsis);
handleChildren(children, ellipsis);
});
}
function setColumns(columns: BasicColumn[] | string[]) {
if (!isArray(columns)) return; if (!isArray(columns)) return;
if (columns.length <= 0) { if (columns.length <= 0) {
@ -116,15 +136,30 @@ export function useColumns(
} }
const firstColumn = columns[0]; const firstColumn = columns[0];
if (isObject(firstColumn)) { if (isObject(firstColumn)) {
columnsRef.value = columns as any; columnsRef.value = columns as BasicColumn[];
} else { } else {
const newColumns = unref(cacheColumnsRef).filter((item) => const newColumns = cacheColumns.filter(
(columns as string[]).includes(`${item.key}`! || item.dataIndex!) (item) =>
(item.dataIndex || `${item.key}`) &&
(columns as string[]).includes(`${item.key}`! || item.dataIndex!)
); );
columnsRef.value = newColumns; columnsRef.value = newColumns;
} }
} }
return { getColumnsRef, setColumns }; function getColumns(opt?: GetColumnsParams) {
const { ignoreIndex, ignoreAction } = opt || {};
let columns = toRaw(unref(getColumnsRef));
if (ignoreIndex) {
columns = columns.filter((item) => item.flag !== INDEX_COLUMN_FLAG);
}
if (ignoreAction) {
columns = columns.filter((item) => item.flag !== ACTION_COLUMN_FLAG);
}
return columns;
}
return { getColumnsRef, getColumns, setColumns };
} }

View File

@ -0,0 +1,90 @@
import type { ComputedRef } from 'vue';
import type { BasicTableProps } from '../types/table';
import { unref } from 'vue';
import { ROW_KEY } from '../const';
import { isString, isFunction } from '/@/utils/is';
interface Options {
setSelectedRowKeys: (keys: string[]) => void;
getSelectRowKeys: () => string[];
clearSelectedRowKeys: () => void;
emit: EmitType;
getAutoCreateKey: ComputedRef<boolean | undefined>;
}
function getKey(
record: Recordable,
rowKey: string | ((record: Record<string, any>) => string) | undefined,
autoCreateKey?: boolean
) {
if (!rowKey || autoCreateKey) {
return record[ROW_KEY];
}
if (isString(rowKey)) {
return record[rowKey];
}
if (isFunction(rowKey)) {
return record[rowKey(record)];
}
return null;
}
export function useCustomRow(
propsRef: ComputedRef<BasicTableProps>,
{ setSelectedRowKeys, getSelectRowKeys, getAutoCreateKey, clearSelectedRowKeys, emit }: Options
) {
const customRow = (record: Recordable, index: number) => {
return {
onClick: (e: Event) => {
emit('row-click', record, index, e);
e?.stopPropagation();
const { rowSelection, rowKey, clickToRowSelect } = unref(propsRef);
if (!rowSelection || !clickToRowSelect) return;
const keys = getSelectRowKeys();
const key = getKey(record, rowKey, unref(getAutoCreateKey));
if (!key) return;
const isCheckbox = rowSelection.type === 'checkbox';
if (isCheckbox) {
if (!keys.includes(key)) {
setSelectedRowKeys([...keys, key]);
return;
}
const keyIndex = keys.findIndex((item) => item === key);
keys.splice(keyIndex, 1);
setSelectedRowKeys(keys);
return;
}
const isRadio = rowSelection.type === 'radio';
if (isRadio) {
if (!keys.includes(key)) {
if (keys.length) {
clearSelectedRowKeys();
}
setSelectedRowKeys([key]);
return;
}
clearSelectedRowKeys();
}
},
onDblclick: (event: Event) => {
emit('row-dbClick', record, index, event);
},
onContextmenu: (event: Event) => {
emit('row-contextmenu', record, index, event);
},
onMouseenter: (event: Event) => {
emit('row-mouseenter', record, index, event);
},
onMouseleave: (event: Event) => {
emit('row-mouseleave', record, index, event);
},
};
};
return {
customRow,
};
}

View File

@ -1,7 +1,7 @@
import type { BasicTableProps, FetchParams } from '../types/table'; import type { BasicTableProps, FetchParams } from '../types/table';
import type { PaginationProps } from '../types/pagination'; import type { PaginationProps } from '../types/pagination';
import { watch, ref, unref, ComputedRef, computed, onMounted, Ref } from 'vue'; import { ref, unref, ComputedRef, computed, onMounted, watchEffect } from 'vue';
import { useTimeoutFn } from '/@/hooks/core/useTimeout'; import { useTimeoutFn } from '/@/hooks/core/useTimeout';
@ -9,39 +9,28 @@ import { buildUUID } from '/@/utils/uuid';
import { isFunction, isBoolean } from '/@/utils/is'; import { isFunction, isBoolean } from '/@/utils/is';
import { get } from 'lodash-es'; import { get } from 'lodash-es';
import { useProps } from './useProps'; import { FETCH_SETTING, ROW_KEY, PAGE_SIZE } from '../const';
import { FETCH_SETTING, ROW_KEY } from '../const';
interface ActionType { interface ActionType {
getPaginationRef: ComputedRef<false | PaginationProps>; getPaginationInfo: ComputedRef<boolean | PaginationProps>;
setPagination: (info: Partial<PaginationProps>) => void; setPagination: (info: Partial<PaginationProps>) => void;
loadingRef: Ref<boolean | undefined>; setLoading: (loading: boolean) => void;
getFieldsValue: () => { getFieldsValue: () => Recordable;
[field: string]: any;
};
} }
export function useDataSource( export function useDataSource(
refProps: ComputedRef<BasicTableProps>, propsRef: ComputedRef<BasicTableProps>,
{ getPaginationRef, setPagination, loadingRef, getFieldsValue }: ActionType, { getPaginationInfo, setPagination, setLoading, getFieldsValue }: ActionType,
emit: EmitType emit: EmitType
) { ) {
const { propsRef } = useProps(refProps); const dataSourceRef = ref<Recordable[]>([]);
const dataSourceRef = ref<any[]>([]); watchEffect(() => {
const { dataSource, api } = unref(propsRef);
watch( !api && dataSource && (dataSourceRef.value = dataSource);
() => unref(propsRef).dataSource, });
(data: any[]) => {
const { api } = unref(propsRef);
!api && (dataSourceRef.value = data);
},
{ immediate: true }
);
function setTableKey(items: any[]) { function setTableKey(items: any[]) {
if (!items || !Array.isArray(items)) { if (!items || !Array.isArray(items)) return;
return;
}
items.forEach((item) => { items.forEach((item) => {
if (!item[ROW_KEY]) { if (!item[ROW_KEY]) {
item[ROW_KEY] = buildUUID(); item[ROW_KEY] = buildUUID();
@ -51,10 +40,16 @@ export function useDataSource(
} }
}); });
} }
const getAutoCreateKey = computed(() => { const getAutoCreateKey = computed(() => {
return unref(propsRef).autoCreateKey && !unref(propsRef).rowKey; return unref(propsRef).autoCreateKey && !unref(propsRef).rowKey;
}); });
const getRowKey = computed(() => {
const { rowKey } = unref(propsRef);
return unref(getAutoCreateKey) ? ROW_KEY : rowKey;
});
const getDataSourceRef = computed(() => { const getDataSourceRef = computed(() => {
const dataSource = unref(dataSourceRef); const dataSource = unref(dataSourceRef);
if (!dataSource || dataSource.length === 0) { if (!dataSource || dataSource.length === 0) {
@ -86,20 +81,20 @@ export function useDataSource(
); );
if (!api || !isFunction(api)) return; if (!api || !isFunction(api)) return;
try { try {
loadingRef.value = true; setLoading(true);
const { pageField, sizeField, listField, totalField } = fetchSetting || FETCH_SETTING; const { pageField, sizeField, listField, totalField } = fetchSetting || FETCH_SETTING;
let pageParams: any = {}; let pageParams: Recordable = {};
const { current, pageSize } = unref(getPaginationRef) as PaginationProps; const { current = 1, pageSize = PAGE_SIZE } = unref(getPaginationInfo) as PaginationProps;
if (isBoolean(getPaginationRef)) { if (isBoolean(getPaginationInfo)) {
pageParams = {}; pageParams = {};
} else { } else {
pageParams[pageField] = (opt && opt.page) || current; pageParams[pageField] = (opt && opt.page) || current;
pageParams[sizeField] = pageSize; pageParams[sizeField] = pageSize;
} }
let params: any = { let params: Recordable = {
...pageParams, ...pageParams,
...(useSearchForm ? getFieldsValue() : {}), ...(useSearchForm ? getFieldsValue() : {}),
...searchInfo, ...searchInfo,
@ -112,18 +107,21 @@ export function useDataSource(
} }
const res = await api(params); const res = await api(params);
let resultItems: any[] = get(res, listField);
const resultTotal: number = get(res, totalField); const isArrayResult = Array.isArray(res);
let resultItems: Recordable[] = isArrayResult ? res : get(res, listField);
const resultTotal: number = isArrayResult ? 0 : get(res, totalField);
// 假如数据变少导致总页数变少并小于当前选中页码通过getPaginationRef获取到的页码是不正确的需获取正确的页码再次执行 // 假如数据变少导致总页数变少并小于当前选中页码通过getPaginationRef获取到的页码是不正确的需获取正确的页码再次执行
var currentTotalPage = Math.ceil(resultTotal / pageSize); const currentTotalPage = Math.ceil(resultTotal / pageSize);
if (current > currentTotalPage) { if (current > currentTotalPage) {
setPagination({ setPagination({
current: currentTotalPage, current: currentTotalPage,
}); });
fetch(opt); fetch(opt);
} }
if (afterFetch && isFunction(afterFetch)) { if (afterFetch && isFunction(afterFetch)) {
resultItems = afterFetch(resultItems) || resultItems; resultItems = afterFetch(resultItems) || resultItems;
} }
@ -147,20 +145,35 @@ export function useDataSource(
total: 0, total: 0,
}); });
} finally { } finally {
loadingRef.value = false; setLoading(false);
// setSearchFormLoading(false);
} }
} }
function setTableData(values: any[]) { function setTableData<T = Recordable>(values: T[]) {
dataSourceRef.value = values; dataSourceRef.value = values;
} }
function getDataSource<T = Recordable>() {
return getDataSourceRef.value as T[];
}
async function reload(opt?: FetchParams) {
await fetch(opt);
}
onMounted(() => { onMounted(() => {
// 转异步任务
useTimeoutFn(() => { useTimeoutFn(() => {
unref(propsRef).immediate && fetch(); unref(propsRef).immediate && fetch();
}, 0); }, 0);
}); });
return { getDataSourceRef, setTableData, getAutoCreateKey, fetch: fetch }; return {
getDataSourceRef,
getDataSource,
getRowKey,
setTableData,
getAutoCreateKey,
fetch,
reload,
};
} }

View File

@ -1,15 +1,20 @@
import { watch, ref, ComputedRef, unref } from 'vue'; import { ref, ComputedRef, unref, computed, watchEffect } from 'vue';
import { BasicTableProps } from '../types/table'; import type { BasicTableProps } from '../types/table';
import { useProps } from './useProps';
export function useLoading(refProps: ComputedRef<BasicTableProps>) {
const { propsRef } = useProps(refProps);
const loadingRef = ref(unref(propsRef).loading); export function useLoading(props: ComputedRef<BasicTableProps>) {
watch( const loadingRef = ref(unref(props).loading);
() => unref(propsRef).loading,
(v: boolean) => { watchEffect(() => {
loadingRef.value = v; loadingRef.value = unref(props).loading;
} });
);
return { loadingRef }; const getLoading = computed(() => {
return unref(loadingRef);
});
function setLoading(loading: boolean) {
loadingRef.value = loading;
}
return { getLoading, setLoading };
} }

View File

@ -7,16 +7,30 @@ import { LeftOutlined, RightOutlined } from '@ant-design/icons-vue';
import { isBoolean } from '/@/utils/is'; import { isBoolean } from '/@/utils/is';
import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '../const'; import { PAGE_SIZE, PAGE_SIZE_OPTIONS } from '../const';
import { useProps } from './useProps';
import { useI18n } from '/@/hooks/web/useI18n'; import { useI18n } from '/@/hooks/web/useI18n';
const { t } = useI18n(); interface ItemRender {
page: number;
type: 'page' | 'prev' | 'next';
originalElement: any;
}
function itemRender({ page, type, originalElement }: ItemRender) {
if (type === 'prev') {
return page === 0 ? null : <LeftOutlined />;
} else if (type === 'next') {
return page === 1 ? null : <RightOutlined />;
}
return originalElement;
}
export function usePagination(refProps: ComputedRef<BasicTableProps>) { export function usePagination(refProps: ComputedRef<BasicTableProps>) {
const configRef = ref<PaginationProps>({}); const configRef = ref<PaginationProps>({});
const { propsRef } = useProps(refProps);
const getPaginationRef = computed((): PaginationProps | false => { const { t } = useI18n();
const { pagination } = unref(propsRef); const getPaginationInfo = computed((): PaginationProps | boolean => {
const { pagination } = unref(refProps);
if (isBoolean(pagination) && !pagination) { if (isBoolean(pagination) && !pagination) {
return false; return false;
} }
@ -28,20 +42,7 @@ export function usePagination(refProps: ComputedRef<BasicTableProps>) {
showTotal: (total) => t('component.table.total', { total }), showTotal: (total) => t('component.table.total', { total }),
showSizeChanger: true, showSizeChanger: true,
pageSizeOptions: PAGE_SIZE_OPTIONS, pageSizeOptions: PAGE_SIZE_OPTIONS,
itemRender: ({ page, type, originalElement }) => { itemRender: itemRender,
if (type === 'prev') {
if (page === 0) {
return null;
}
return <LeftOutlined />;
} else if (type === 'next') {
if (page === 1) {
return null;
}
return <RightOutlined />;
}
return originalElement;
},
showQuickJumper: true, showQuickJumper: true,
...(isBoolean(pagination) ? {} : pagination), ...(isBoolean(pagination) ? {} : pagination),
...unref(configRef), ...unref(configRef),
@ -49,10 +50,15 @@ export function usePagination(refProps: ComputedRef<BasicTableProps>) {
}); });
function setPagination(info: Partial<PaginationProps>) { function setPagination(info: Partial<PaginationProps>) {
const paginationInfo = unref(getPaginationInfo);
configRef.value = { configRef.value = {
...unref(getPaginationRef), ...(!isBoolean(paginationInfo) ? paginationInfo : {}),
...info, ...info,
}; };
} }
return { getPaginationRef, setPagination };
function getPagination() {
return unref(getPaginationInfo);
}
return { getPagination, getPaginationInfo, setPagination };
} }

View File

@ -1,21 +0,0 @@
import { Ref, ref, watch, unref } from 'vue';
import type { BasicTableProps } from '../types/table';
/**
* @description:
* @Date: 2020-05-12 13:20:37
*/
export function useProps(props: Readonly<Ref<BasicTableProps>>) {
const propsRef = (ref<BasicTableProps>(unref(props)) as unknown) as Ref<BasicTableProps>;
watch(
() => props.value,
(v) => {
propsRef.value = unref(v);
},
{
immediate: false,
}
);
return { propsRef };
}

View File

@ -1,17 +1,14 @@
import type { BasicTableProps, TableRowSelection } from '../types/table'; import type { BasicTableProps, TableRowSelection } from '../types/table';
import { computed, ref, unref, ComputedRef } from 'vue'; import { computed, ref, unref, ComputedRef } from 'vue';
import { useProps } from './useProps';
/* eslint-disable */ /* eslint-disable */
export function useRowSelection(refProps: ComputedRef<BasicTableProps>, emit: EmitType) { export function useRowSelection(propsRef: ComputedRef<BasicTableProps>, emit: EmitType) {
const { propsRef } = useProps(refProps);
const selectedRowKeysRef = ref<string[]>([]); const selectedRowKeysRef = ref<string[]>([]);
const selectedRowRef = ref<any[]>([]); const selectedRowRef = ref<Recordable[]>([]);
const getRowSelectionRef = computed((): TableRowSelection | null => { const getRowSelectionRef = computed((): TableRowSelection | null => {
const rowSelection = unref(propsRef).rowSelection; const { rowSelection } = unref(propsRef);
if (!rowSelection) { if (!rowSelection) {
return null; return null;
} }
@ -46,11 +43,14 @@ export function useRowSelection(refProps: ComputedRef<BasicTableProps>, emit: Em
unref(selectedRowKeysRef).splice(index, 1); unref(selectedRowKeysRef).splice(index, 1);
} }
} }
function getSelectRowKeys() { function getSelectRowKeys() {
return unref(selectedRowKeysRef); return unref(selectedRowKeysRef);
} }
function getSelectRows() {
return unref(selectedRowRef); function getSelectRows<T = Recordable>() {
// const ret = toRaw(unref(selectedRowRef)).map((item) => toRaw(item));
return unref(selectedRowRef) as T[];
} }
return { return {

View File

@ -14,10 +14,11 @@ export function useTable(
const loadedRef = ref<Nullable<boolean>>(false); const loadedRef = ref<Nullable<boolean>>(false);
function register(instance: TableActionType) { function register(instance: TableActionType) {
onUnmounted(() => { isProdMode() &&
tableRef.value = null; onUnmounted(() => {
loadedRef.value = null; tableRef.value = null;
}); loadedRef.value = null;
});
if (unref(loadedRef) && isProdMode() && instance === unref(tableRef)) { if (unref(loadedRef) && isProdMode() && instance === unref(tableRef)) {
return; return;

View File

@ -1,57 +1,63 @@
import type { BasicTableProps } from '../types/table'; import type { BasicTableProps } from '../types/table';
import { computed, Ref, onMounted, unref, ref, nextTick, ComputedRef, watch } from 'vue'; import type { Ref, ComputedRef } from 'vue';
import { computed, unref, ref, nextTick, watchEffect } from 'vue';
import { getViewportOffset } from '/@/utils/domUtils'; import { getViewportOffset } from '/@/utils/domUtils';
import { isBoolean } from '/@/utils/is'; import { isBoolean } from '/@/utils/is';
import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn'; import { useWindowSizeFn } from '/@/hooks/event/useWindowSizeFn';
import { useProps } from './useProps';
import { useModalContext } from '/@/components/Modal'; import { useModalContext } from '/@/components/Modal';
export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRef: Ref<any>) { export function useTableScroll(
const { propsRef } = useProps(refProps); propsRef: ComputedRef<BasicTableProps>,
tableElRef: Ref<ComponentRef>
const tableHeightRef: Ref<number | null> = ref(null); ) {
const tableHeightRef: Ref<Nullable<number>> = ref(null);
const modalFn = useModalContext(); const modalFn = useModalContext();
watch( const getCanResize = computed(() => {
() => unref(propsRef).canResize, const { canResize, scroll } = unref(propsRef);
() => { return canResize && !(scroll || {}).y;
redoHeight(); });
}
); watchEffect(() => {
redoHeight();
});
function redoHeight() { function redoHeight() {
const { canResize } = unref(propsRef); if (unref(getCanResize)) {
nextTick(() => {
if (!canResize) return; calcTableHeight();
calcTableHeight(); });
}
} }
// No need to repeat queries
let paginationEl: HTMLElement | null; let paginationEl: HTMLElement | null;
let footerEl: HTMLElement | null; let footerEl: HTMLElement | null;
async function calcTableHeight() { async function calcTableHeight() {
const { canResize, resizeHeightOffset, pagination, maxHeight } = unref(propsRef); const { resizeHeightOffset, pagination, maxHeight } = unref(propsRef);
if (!canResize) return; if (!unref(getCanResize)) return;
await nextTick(); await nextTick();
const table = unref(tableElRef) as any; const table = unref(tableElRef);
if (!table) return; if (!table) return;
const tableEl: Element = table.$el; const tableEl: Element = table.$el;
if (!tableEl) return; if (!tableEl) return;
const headEl = tableEl.querySelector('.ant-table-thead '); const headEl = tableEl.querySelector('.ant-table-thead ');
if (!headEl) return; if (!headEl) return;
// 表格距离底部高度 // Table height from bottom
const { bottomIncludeBody } = getViewportOffset(headEl); const { bottomIncludeBody } = getViewportOffset(headEl);
// 表格高度+距离底部高度-自定义偏移量 // Table height from bottom height-custom offset
const paddingHeight = 32; const paddingHeight = 32;
const borderHeight = 2 * 2; const borderHeight = 2 * 2;
// 分页器高度 // Pager height
let paginationHeight = 2; let paginationHeight = 2;
if (!isBoolean(pagination)) { if (!isBoolean(pagination)) {
if (!paginationEl) { if (!paginationEl) {
@ -61,7 +67,7 @@ export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRe
const offsetHeight = paginationEl.offsetHeight; const offsetHeight = paginationEl.offsetHeight;
paginationHeight += offsetHeight || 0; paginationHeight += offsetHeight || 0;
} else { } else {
// TODO 先固定24 // TODO First fix 24
paginationHeight += 24; paginationHeight += 24;
} }
} }
@ -75,11 +81,13 @@ export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRe
footerHeight += offsetHeight || 0; footerHeight += offsetHeight || 0;
} }
} }
let headerHeight = 0; let headerHeight = 0;
if (headEl) { if (headEl) {
headerHeight = (headEl as HTMLElement).offsetHeight; headerHeight = (headEl as HTMLElement).offsetHeight;
} }
tableHeightRef.value =
const height =
bottomIncludeBody - bottomIncludeBody -
(resizeHeightOffset || 0) - (resizeHeightOffset || 0) -
paddingHeight - paddingHeight -
@ -89,27 +97,14 @@ export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRe
headerHeight; headerHeight;
setTimeout(() => { setTimeout(() => {
tableHeightRef.value = tableHeightRef.value = (height > maxHeight! ? (maxHeight as number) : height) ?? height;
tableHeightRef.value! > maxHeight! ? (maxHeight as number) : tableHeightRef.value; // Solve the problem of modal adaptive height calculation when the form is placed in the modal
// 解决表格放modal内的时候modal自适应高度计算问题
modalFn?.redoModalHeight?.(); modalFn?.redoModalHeight?.();
}, 16); }, 0);
} }
const getCanResize = computed(() => {
const { canResize, scroll } = unref(propsRef);
return canResize && !(scroll || {}).y;
});
useWindowSizeFn(calcTableHeight, 100); useWindowSizeFn(calcTableHeight, 100);
onMounted(() => {
if (unref(getCanResize)) {
nextTick(() => {
calcTableHeight();
});
}
});
const getScrollRef = computed(() => { const getScrollRef = computed(() => {
const tableHeight = unref(tableHeightRef); const tableHeight = unref(tableHeightRef);
const { canResize, scroll } = unref(propsRef); const { canResize, scroll } = unref(propsRef);
@ -121,5 +116,6 @@ export function useTableScroll(refProps: ComputedRef<BasicTableProps>, tableElRe
...scroll, ...scroll,
}; };
}); });
return { getScrollRef, redoHeight }; return { getScrollRef, redoHeight };
} }

View File

@ -0,0 +1,18 @@
import type { ComputedRef } from 'vue';
import type { BasicTableProps, TableCustomRecord } from '../types/table';
import { unref } from 'vue';
import { isFunction } from '/@/utils/is';
export function useTableStyle(propsRef: ComputedRef<BasicTableProps>) {
function getRowClassName(record: TableCustomRecord, index: number) {
const { striped, rowClassName } = unref(propsRef);
if (!striped) return;
if (rowClassName && isFunction(rowClassName)) {
return rowClassName(record);
}
return (index || 0) % 2 === 1 ? 'basic-table-row__striped' : '';
}
return {
getRowClassName,
};
}

View File

@ -14,6 +14,7 @@ import { propTypes } from '/@/utils/propTypes';
// 注释看 types/table // 注释看 types/table
export const basicProps = { export const basicProps = {
clickToRowSelect: propTypes.bool.def(true),
tableSetting: { tableSetting: {
type: Object as PropType<TableSetting>, type: Object as PropType<TableSetting>,
}, },
@ -34,7 +35,6 @@ export const basicProps = {
}, },
canColDrag: propTypes.bool.def(true), canColDrag: propTypes.bool.def(true),
isTreeTable: propTypes.bool,
api: { api: {
type: Function as PropType<(...arg: any[]) => Promise<any>>, type: Function as PropType<(...arg: any[]) => Promise<any>>,
default: null, default: null,

View File

@ -167,20 +167,6 @@
} }
} }
.ant-radio {
&-inner {
border-color: @text-color-base;
}
}
.ant-checkbox {
&:not(.ant-checkbox-checked) {
.ant-checkbox-inner {
border-color: @text-color-base;
}
}
}
.ant-table-bordered .ant-table-thead > tr:not(:last-child) > th, .ant-table-bordered .ant-table-thead > tr:not(:last-child) > th,
.ant-table-tbody > tr > td { .ant-table-tbody > tr > td {
word-break: break-word; word-break: break-word;

View File

@ -124,6 +124,8 @@ export interface TableSetting {
} }
export interface BasicTableProps<T = any> { export interface BasicTableProps<T = any> {
// 点击行选中
clickToRowSelect?: boolean;
// 自定义排序方法 // 自定义排序方法
sortFn?: (sortInfo: SorterResult) => any; sortFn?: (sortInfo: SorterResult) => any;
// 取消表格的默认padding // 取消表格的默认padding
@ -141,8 +143,6 @@ export interface BasicTableProps<T = any> {
showSummary?: boolean; showSummary?: boolean;
// 是否可拖拽列 // 是否可拖拽列
canColDrag?: boolean; canColDrag?: boolean;
// 是否树表
isTreeTable?: boolean;
// 接口请求对象 // 接口请求对象
api?: (...arg: any) => Promise<any>; api?: (...arg: any) => Promise<any>;
// 请求之前处理参数 // 请求之前处理参数
@ -158,7 +158,7 @@ export interface BasicTableProps<T = any> {
// 在开起搜索表单的时候,如果没有数据是否显示表格 // 在开起搜索表单的时候,如果没有数据是否显示表格
emptyDataIsShowTable?: boolean; emptyDataIsShowTable?: boolean;
// 额外的请求参数 // 额外的请求参数
searchInfo?: any; searchInfo?: Recordable;
// 使用搜索表单 // 使用搜索表单
useSearchForm?: boolean; useSearchForm?: boolean;
// 表单配置 // 表单配置
@ -180,9 +180,9 @@ export interface BasicTableProps<T = any> {
// 在分页改变的时候清空选项 // 在分页改变的时候清空选项
clearSelectOnPageChange?: boolean; clearSelectOnPageChange?: boolean;
// //
rowKey?: string | ((record: any) => string); rowKey?: string | ((record: Recordable) => string);
// 数据 // 数据
dataSource?: any[]; dataSource?: Recordable[];
// 标题右侧提示 // 标题右侧提示
titleHelpMessage?: string | string[]; titleHelpMessage?: string | string[];
// 表格滚动最大高度 // 表格滚动最大高度

View File

@ -9,7 +9,8 @@
:loading="loading" :loading="loading"
:striped="striped" :striped="striped"
:bordered="border" :bordered="border"
:pagination="{ pageSize: 20 }" showTableSetting
:pagination="pagination"
> >
<template #toolbar> <template #toolbar>
<a-button type="primary" @click="toggleCanResize"> <a-button type="primary" @click="toggleCanResize">
@ -38,6 +39,7 @@
const loading = ref(false); const loading = ref(false);
const striped = ref(true); const striped = ref(true);
const border = ref(true); const border = ref(true);
const pagination = ref<any>(false);
function toggleCanResize() { function toggleCanResize() {
canResize.value = !canResize.value; canResize.value = !canResize.value;
} }
@ -48,6 +50,7 @@
loading.value = true; loading.value = true;
setTimeout(() => { setTimeout(() => {
loading.value = false; loading.value = false;
pagination.value = { pageSize: 20 };
}, 3000); }, 3000);
} }
function toggleBorder() { function toggleBorder() {
@ -64,6 +67,7 @@
toggleCanResize, toggleCanResize,
toggleLoading, toggleLoading,
toggleBorder, toggleBorder,
pagination,
}; };
}, },
}); });

View File

@ -74,10 +74,10 @@
slots: { customRender: 'action' }, slots: { customRender: 'action' },
}, },
}); });
function handleDelete(record: any) { function handleDelete(record: Recordable) {
console.log('点击了删除', record); console.log('点击了删除', record);
} }
function handleOpen(record: any) { function handleOpen(record: Recordable) {
console.log('点击了启用', record); console.log('点击了启用', record);
} }
return { return {

View File

@ -2,7 +2,6 @@
<div class="p-4"> <div class="p-4">
<BasicTable <BasicTable
:rowSelection="{ type: 'checkbox' }" :rowSelection="{ type: 'checkbox' }"
:isTreeTable="true"
title="树形表格" title="树形表格"
titleHelpMessage="树形组件不能和序列号列同时存在" titleHelpMessage="树形组件不能和序列号列同时存在"
:columns="columns" :columns="columns"

View File

@ -44,12 +44,13 @@
clearSelectedRowKeys, clearSelectedRowKeys,
}, },
] = useTable({ ] = useTable({
canResize: false, canResize: true,
title: 'useTable示例', title: 'useTable示例',
titleHelpMessage: '使用useTable调用表格内方法', titleHelpMessage: '使用useTable调用表格内方法',
api: demoListApi, api: demoListApi,
columns: getBasicColumns(), columns: getBasicColumns(),
rowKey: 'id', rowKey: 'id',
showTableSetting: true,
rowSelection: { rowSelection: {
type: 'checkbox', type: 'checkbox',
}, },

View File

@ -5,13 +5,13 @@ export function getBasicColumns(): BasicColumn[] {
return [ return [
{ {
title: 'ID', title: 'ID',
width: 150,
dataIndex: 'id', dataIndex: 'id',
width: 150,
}, },
{ {
title: '姓名', title: '姓名',
dataIndex: 'name', dataIndex: 'name',
width: 120, width: 150,
}, },
{ {
title: '地址', title: '地址',
@ -20,14 +20,16 @@ export function getBasicColumns(): BasicColumn[] {
{ {
title: '编号', title: '编号',
dataIndex: 'no', dataIndex: 'no',
width: 80, width: 150,
}, },
{ {
title: '开始时间', title: '开始时间',
width: 120,
dataIndex: 'beginTime', dataIndex: 'beginTime',
}, },
{ {
title: '结束时间', title: '结束时间',
width: 120,
sorter: true, sorter: true,
dataIndex: 'endTime', dataIndex: 'endTime',
}, },