vue-vben-admin/src/components/Table/src/BasicTable.vue

277 lines
7.6 KiB
Vue

<template>
<div
ref="wrapRef"
:class="[
prefixCls,
{
[`${prefixCls}-form-container`]: getBindValues.useSearchForm,
[`${prefixCls}--inset`]: getBindValues.inset,
},
]"
>
<BasicForm
submitOnReset
v-bind="getFormProps"
v-if="getBindValues.useSearchForm"
:submitButtonOptions="{ loading: getLoading }"
:tableAction="tableAction"
@register="registerForm"
@submit="handleSearchInfoChange"
@advanced-change="redoHeight"
>
<template #[replaceFormSlotKey(item)]="data" v-for="item in getFormSlotKeys">
<slot :name="item" v-bind="data" />
</template>
</BasicForm>
<Table
ref="tableElRef"
v-bind="getBindValues"
:rowClassName="getRowClassName"
v-show="getEmptyDataIsShowTable"
@change="handleTableChange"
>
<template #[item]="data" v-for="item in Object.keys($slots)">
<slot :name="item" v-bind="data" />
</template>
<template #[`header-${column.dataIndex}`] v-for="column in columns" :key="column.dataIndex">
<HeaderCell :column="column" />
</template>
</Table>
</div>
</template>
<script lang="ts">
import type { BasicTableProps, TableActionType, SizeType } from './types/table';
import { defineComponent, ref, computed, unref } from 'vue';
import { Table } from 'ant-design-vue';
import { BasicForm, useForm } from '/@/components/Form/index';
import { omit } from 'lodash-es';
import { usePagination } from './hooks/usePagination';
import { useColumns } from './hooks/useColumns';
import { useDataSource } from './hooks/useDataSource';
import { useLoading } from './hooks/useLoading';
import { useRowSelection } from './hooks/useRowSelection';
import { useTableScroll } from './hooks/useTableScroll';
import { useCustomRow } from './hooks/useCustomRow';
import { useTableStyle } from './hooks/useTableStyle';
import { useTableHeader } from './hooks/useTableHeader';
import { createTableContext } from './hooks/useTableContext';
import { useTableFooter } from './hooks/useTableFooter';
import { useTableForm } from './hooks/useTableForm';
import { useExpose } from '/@/hooks/core/useExpose';
import { useDesign } from '/@/hooks/web/useDesign';
import { basicProps } from './props';
import { createAsyncComponent } from '/@/utils/factory/createAsyncComponent';
import './style/index.less';
export default defineComponent({
props: basicProps,
components: {
Table,
BasicForm,
HeaderCell: createAsyncComponent(() => import('./components/HeaderCell.vue')),
},
emits: [
'fetch-success',
'fetch-error',
'selection-change',
'register',
'row-click',
'row-dbClick',
'row-contextmenu',
'row-mouseenter',
'row-mouseleave',
'edit-end',
'edit-cancel',
'edit-row-end',
],
setup(props, { attrs, emit, slots }) {
const tableElRef = ref<ComponentRef>(null);
const wrapRef = ref<Nullable<HTMLDivElement>>(null);
const innerPropsRef = ref<Partial<BasicTableProps>>();
const { prefixCls } = useDesign('basic-table');
const [registerForm, formActions] = useForm();
const getProps = computed(() => {
return { ...props, ...unref(innerPropsRef) } as BasicTableProps;
});
const { getLoading, setLoading } = useLoading(getProps);
const {
getPaginationInfo,
getPagination,
setPagination,
setShowPagination,
getShowPagination,
} = usePagination(getProps);
const {
getRowSelection,
getRowSelectionRef,
getSelectRows,
clearSelectedRowKeys,
getSelectRowKeys,
deleteSelectRowByKey,
setSelectedRowKeys,
} = useRowSelection(getProps, emit);
const {
handleTableChange,
getDataSourceRef,
getDataSource,
setTableData,
fetch,
getRowKey,
reload,
getAutoCreateKey,
updateTableData,
} = useDataSource(
getProps,
{
getPaginationInfo,
setLoading,
setPagination,
getFieldsValue: formActions.getFieldsValue,
clearSelectedRowKeys,
},
emit
);
const {
getViewColumns,
getColumns,
setCacheColumnsByField,
setColumns,
getColumnsRef,
getCacheColumns,
} = useColumns(getProps, getPaginationInfo);
const { getScrollRef, redoHeight } = useTableScroll(
getProps,
tableElRef,
getColumnsRef,
getRowSelectionRef
);
const { customRow } = useCustomRow(getProps, {
setSelectedRowKeys,
getSelectRowKeys,
clearSelectedRowKeys,
getAutoCreateKey,
emit,
});
const { getRowClassName } = useTableStyle(getProps, prefixCls);
const { getHeaderProps } = useTableHeader(getProps, slots);
const { getFooterProps } = useTableFooter(
getProps,
getScrollRef,
tableElRef,
getDataSourceRef
);
const {
getFormProps,
replaceFormSlotKey,
getFormSlotKeys,
handleSearchInfoChange,
} = useTableForm(getProps, slots, fetch);
const getBindValues = computed(() => {
let propsData: Recordable = {
size: 'middle',
...attrs,
customRow,
...unref(getProps),
...unref(getHeaderProps),
scroll: unref(getScrollRef),
loading: unref(getLoading),
tableLayout: 'fixed',
rowSelection: unref(getRowSelectionRef),
rowKey: unref(getRowKey),
columns: unref(getViewColumns),
pagination: unref(getPaginationInfo),
dataSource: unref(getDataSourceRef),
footer: unref(getFooterProps),
};
if (slots.expandedRowRender) {
propsData = omit(propsData, 'scroll');
}
return propsData;
});
const getEmptyDataIsShowTable = computed(() => {
const { emptyDataIsShowTable, useSearchForm } = unref(getProps);
if (emptyDataIsShowTable || !useSearchForm) {
return true;
}
return !!unref(getDataSourceRef).length;
});
function setProps(props: Partial<BasicTableProps>) {
innerPropsRef.value = { ...unref(innerPropsRef), ...props };
}
const tableAction: TableActionType = {
reload,
getSelectRows,
clearSelectedRowKeys,
getSelectRowKeys,
deleteSelectRowByKey,
setPagination,
setTableData,
redoHeight,
setSelectedRowKeys,
setColumns,
setLoading,
getDataSource,
setProps,
getRowSelection,
getPaginationRef: getPagination,
getColumns,
getCacheColumns,
emit,
updateTableData,
setShowPagination,
getShowPagination,
setCacheColumnsByField,
getSize: () => {
return unref(getBindValues).size as SizeType;
},
};
createTableContext({ ...tableAction, wrapRef, getBindValues });
useExpose<TableActionType>(tableAction);
emit('register', tableAction, formActions);
return {
tableElRef,
getBindValues,
getLoading,
registerForm,
handleSearchInfoChange,
getEmptyDataIsShowTable,
handleTableChange,
getRowClassName,
wrapRef,
tableAction,
redoHeight,
getFormProps,
replaceFormSlotKey,
getFormSlotKeys,
prefixCls,
columns: getViewColumns,
};
},
});
</script>