import download from '@/utils/download' import { Table, TableExpose } from '@/components/Table' import { ElMessage, ElMessageBox, ElTable } from 'element-plus' import { computed, nextTick, reactive, ref, unref, watch } from 'vue' import type { TableProps } from '@/components/Table/src/types' import { TableSetPropsType } from '@/types/table' const { t } = useI18n() interface ResponseType { list: T[] total?: number } interface UseTableConfig { getListApi: (option: any) => Promise delListApi?: (option: any) => Promise exportListApi?: (option: any) => Promise // 返回数据格式配置 response?: ResponseType // 默认传递的参数 defaultParams?: Recordable props?: TableProps } interface TableObject { pageSize: number currentPage: number total: number tableList: T[] params: any loading: boolean exportLoading: boolean currentRow: Nullable } export const useTable = (config?: UseTableConfig) => { const tableObject = reactive>({ // 页数 pageSize: 10, // 当前页 currentPage: 1, // 总条数 total: 10, // 表格数据 tableList: [], // AxiosConfig 配置 params: { ...(config?.defaultParams || {}) }, // 加载中 loading: true, // 导出加载中 exportLoading: false, // 当前行的数据 currentRow: null }) const paramsObj = computed(() => { return { ...tableObject.params, pageSize: tableObject.pageSize, pageNo: tableObject.currentPage } }) watch( () => tableObject.currentPage, () => { methods.getList() } ) watch( () => tableObject.pageSize, () => { // 当前页不为1时,修改页数后会导致多次调用getList方法 if (tableObject.currentPage === 1) { methods.getList() } else { tableObject.currentPage = 1 methods.getList() } } ) // Table实例 const tableRef = ref() // ElTable实例 const elTableRef = ref>() const register = (ref: typeof Table & TableExpose, elRef: ComponentRef) => { tableRef.value = ref elTableRef.value = elRef } const getTable = async () => { await nextTick() const table = unref(tableRef) if (!table) { console.error('The table is not registered. Please use the register method to register') } return table } const delData = async (ids: string | number | string[] | number[]) => { let idsLength = 1 if (ids instanceof Array) { idsLength = ids.length await Promise.all( ids.map(async (id: string | number) => { await (config?.delListApi && config?.delListApi(id)) }) ) } else { await (config?.delListApi && config?.delListApi(ids)) } ElMessage.success(t('common.delSuccess')) // 计算出临界点 tableObject.currentPage = tableObject.total % tableObject.pageSize === idsLength || tableObject.pageSize === 1 ? tableObject.currentPage > 1 ? tableObject.currentPage - 1 : tableObject.currentPage : tableObject.currentPage await methods.getList() } const methods = { getList: async () => { tableObject.loading = true const res = await config?.getListApi(unref(paramsObj)).finally(() => { tableObject.loading = false }) if (res) { tableObject.tableList = (res as unknown as ResponseType).list tableObject.total = (res as unknown as ResponseType).total ?? 0 } }, setProps: async (props: TableProps = {}) => { const table = await getTable() table?.setProps(props) }, setColumn: async (columnProps: TableSetPropsType[]) => { const table = await getTable() table?.setColumn(columnProps) }, getSelections: async () => { const table = await getTable() return (table?.selections || []) as T[] }, // 与Search组件结合 setSearchParams: (data: Recordable) => { tableObject.params = Object.assign(tableObject.params, { pageSize: tableObject.pageSize, pageNo: 1, ...data }) // 页码不等于1时更新页码重新获取数据,页码等于1时重新获取数据 if (tableObject.currentPage !== 1) { tableObject.currentPage = 1 } else { methods.getList() } }, // 删除数据 delList: async ( ids: string | number | string[] | number[], multiple: boolean, message = true ) => { const tableRef = await getTable() if (multiple) { if (!tableRef?.selections.length) { ElMessage.warning(t('common.delNoData')) return } } if (message) { ElMessageBox.confirm(t('common.delMessage'), t('common.confirmTitle'), { confirmButtonText: t('common.ok'), cancelButtonText: t('common.cancel'), type: 'warning' }).then(async () => { await delData(ids) }) } else { await delData(ids) } }, // 导出列表 exportList: async (fileName: string) => { tableObject.exportLoading = true ElMessageBox.confirm(t('common.exportMessage'), t('common.confirmTitle'), { confirmButtonText: t('common.ok'), cancelButtonText: t('common.cancel'), type: 'warning' }) .then(async () => { const res = await config?.exportListApi?.(unref(paramsObj) as unknown as T) if (res) { download.excel(res as unknown as Blob, fileName) } }) .finally(() => { tableObject.exportLoading = false }) } } config?.props && methods.setProps(config.props) return { register, elTableRef, tableObject, methods, // add by 芋艿:返回 tableMethods 属性,和 tableObject 更统一 tableMethods: methods } }