import { ref, ComputedRef, unref, computed, onMounted, watchEffect, watch } from 'vue'; import type { BasicTableProps, SorterResult } from '../types/table'; import type { PaginationProps } from '../types/pagination'; import { isFunction, isBoolean } from '@/utils/is'; import { APISETTING, DEFAULTPAGESIZE } from '../const'; export function useDataSource( propsRef: ComputedRef, { getPaginationInfo, setPagination, setLoading, tableData }, emit, ) { const dataSourceRef = ref([]); watchEffect(() => { tableData.value = unref(dataSourceRef); }); watch( () => unref(propsRef).dataSource, () => { const { dataSource, request }: any = unref(propsRef); !request && dataSource && (dataSourceRef.value = dataSource); }, { immediate: true, }, ); const getRowKey = computed(() => { const { rowKey }: any = unref(propsRef); return rowKey ? rowKey : () => { return 'key'; }; }); const getDataSourceRef = computed(() => { const dataSource = unref(dataSourceRef); if (!dataSource || dataSource.length === 0) { return unref(dataSourceRef); } return unref(dataSourceRef); }); function tableChange( pagination: PaginationProps, filters?: Partial>, sorter?: SorterResult, ) { const { sortFn, filterFn } = unref(propsRef); setPagination(pagination); const params: Recordable = {}; if (sorter && isFunction(sortFn)) { const sortInfo = sortFn(sorter); params.sortInfo = sortInfo; } if (filters && isFunction(filterFn)) { const filterInfo = filterFn(filters); params.filterInfo = filterInfo; } fetch(params); } async function fetch(opt?, isRestReload?) { try { setLoading(true); const { request, pagination }: any = unref(propsRef); if (!request) return; //组装分页信息 const pageField = APISETTING.pageField; const sizeField = APISETTING.sizeField; const totalField = APISETTING.totalField; const listField = APISETTING.listField; const itemCount = APISETTING.countField; let pageParams = {}; const { current = 1, pageSize = DEFAULTPAGESIZE } = unref( getPaginationInfo, ) as PaginationProps; if ((isBoolean(pagination) && !pagination) || isBoolean(getPaginationInfo)) { pageParams = {}; } else { pageParams[pageField] = (opt && opt[pageField]) || current; pageParams[sizeField] = pageSize; } const params = { ...pageParams, ...pagination, ...opt, }; //如果是重置刷新,重置页码 if (isRestReload) { params[pageField] = 1; setPagination({ current: 1, }); } const res = await request(params); const resultTotal = res[totalField] || 0; const currentPage = res['current']; const total = res[itemCount] || 0; const results = res[listField] ? res[listField] : []; // 如果数据异常,需获取正确的页码再次执行 if (resultTotal) { const currentTotalPage = Math.ceil(total / pageSize); if (current > currentTotalPage) { setPagination({ current: currentTotalPage, [itemCount]: total, }); return await fetch(opt); } } dataSourceRef.value = results; setPagination({ // [pageField]: currentPage, current: currentPage, [totalField]: resultTotal, [itemCount]: total, }); if (opt && currentPage) { setPagination({ current: currentPage || 1, }); } emit('fetch-success', { items: unref(results), resultTotal, }); } catch (error) { console.error(error); const totalField = APISETTING.totalField; emit('fetch-error', error); dataSourceRef.value = []; setPagination({ [totalField]: 0, }); } finally { setLoading(false); } } onMounted(() => { setTimeout(() => { fetch(); }, 16); }); function setTableData(values: T[]) { dataSourceRef.value = values; } function getDataSource() { return getDataSourceRef.value as T[]; } async function reload(opt?) { await fetch(opt); } async function restReload(opt?) { await fetch(opt, true); } async function updateTableData(index: number, key: string, value: any) { const record = dataSourceRef.value[index]; if (record) { dataSourceRef.value[index][key] = value; } return dataSourceRef.value[index]; } return { fetch, getRowKey, getDataSourceRef, getDataSource, tableChange, setTableData, reload, restReload, updateTableData, }; }