useTable_crud.ts
import { useEffect, useState, Key } from 'react'; import { showMessage } from 'common/props/messageProps'; import axios from 'axios'; import { ChangeDataParams, UseGetTableProps, changePageType, changeSelectType, getDeleteNumType, handleChangeDataParams, handleCrudParams, onTableRowSelectType, recordType, } from '../type'; import { CustomPagination } from 'common/props/tableProps'; import { useDidUpdateEffect } from 'common/hooks/useDidUpdateEffect'; import { getTableRowSelection } from 'common/props/tableProps/rowSelection'; import { axiosData } from 'common/hooks/axios'; //T:表格数据类型 U:参数类型 const useGetTable = <T, U = {}>(props: UseGetTableProps<U>) => { //url:接口路径,params:参数,isUseDidUpdateEffect:是否初次加载,type:(1:get 分页(默认) 2:get 不分页 3.post 分页 4.post 不分页) const { url, params, isUseDidUpdateEffect, type = 1 } = props; const [tableLoading, setTableLoading] = useState(false); //表格加载状态 const [tableData, setTableData] = useState<T[]>([]); //表格数据 const [tableTotal, setTableTotal] = useState(0); //表格总数 const [current, setCurrent] = useState<number>(1); //当前是第几页 const [pageSize, setPageSize] = useState<number>(10); //一页展示多少 const [searchValue, setSearchValue] = useState<recordType>(); //搜索框搜索的值 const [selectedRowKeys, setSelectRowKeys] = useState<Key[]>([]); //表格勾选的key const [selectedRows, setSelectedRows] = useState<T[]>([]); //表格勾选的数据 const [recordData, setRecordData] = useState<T | {}>({}); //打开模态框的记录 const [crudType, setCrudType] = useState<number>(2); //模态框的类型 0:修改 1:新建 2:查看 const [isShowModal, setIsShowModal] = useState(false); //是否打开模态框 const [modalTitle, setModalTitle] = useState(''); //模态框的表头 const tableDataParams = [searchValue, current, pageSize]; //勾选 const changeSelect: changeSelectType<T> = (selectedRowKeys, selectedRows) => { setSelectRowKeys(selectedRowKeys); setSelectedRows(selectedRows); }; //改变页数 const changePage: changePageType = (current, pageSize) => { setCurrent(current); setPageSize(pageSize); }; //重置勾选 const resetSelect = () => { setSelectRowKeys([]); setSelectedRows([]); }; //表单数据 const getSearchValue = (v: recordType) => { setSearchValue(v); setCurrent(1); }; //根据类型获取表格数据 const getTableData = async () => { try { setTableLoading(true); const parament = { ...searchValue, ...params, current, pageSize }; if (type === 1) { const { data } = await axios.get(url, { params: parament, }); setTableData(data.data); setTableTotal(data.total); } else if (type === 2) { const { data } = await axios.get(url, { params: { ...searchValue, ...params } }); if (data.code) { setTableData(data.data); setTableTotal(data.data.length); } else { setTableData(data); setTableTotal(data.length); } } else if (type === 3) { const { data } = await axios.post(url, { ...parament }); setTableData(data.data); setTableTotal(data.total); } else if (type === 4) { const { data } = await axios.post(url, { ...searchValue, ...params }); setTableData(data); setTableTotal(data.length); } } catch (error) { showMessage('error', (error as Error).message); } finally { setTableLoading(false); } }; //重新加载表格数据数据和重置操作 const reloadData = () => { getTableData(); resetSelect(); }; const tablePagination = { ...CustomPagination(current, pageSize, tableTotal), onChange: changePage }; //table 分页 //table 勾选 const tableSelect = { onChange: changeSelect, selectedRowKeys, selectedRows, preserveSelectedRowKeys: true, }; //loading 和table数据 const LoadingAndData = { spinning: tableLoading, dataSource: tableData, }; //message的类型 const messageMethod = (v: boolean) => { return v ? 'success' : 'error'; }; //删除 const handleDelete: ChangeDataParams = async (url, params, num, method = 'post') => { axiosData(url, params, method).then((res) => { const method = messageMethod(res.success); if (res.success) { reloadData(); getDeleteNum(num); } showMessage(method, res.message); }); }; //创建/修改/复制调用接口 url:接口路径,params:接口参数,method:请求方式 const handleChangeData: handleChangeDataParams = async (url, params, method = 'post') => { axiosData(url, params, method).then((res) => { const method = messageMethod(res.success); if (res.success) { handleCancel(); reloadData(); } showMessage(method, res.message); }); }; //增删查 打开modal操作 record:当前点击的记录,title:打开的弹窗的标题,crudType:0:修改 1 新建 2查看 const handleCrud: handleCrudParams = (record, title, crudType) => { setModalTitle(title); setRecordData(record); setCrudType(crudType); setIsShowModal(true); }; //关闭模态框 const handleCancel = () => { setIsShowModal(false); }; //获取删除后的current const getDeleteNum: getDeleteNumType = (num) => { let updatedCurrent = 1; if (current !== 1) { updatedCurrent = Math.ceil((tableTotal - (num ? num : selectedRowKeys.length)) / pageSize); // 更新后的当前页码 setCurrent(updatedCurrent); } }; //行选 const onTableRowSelect: onTableRowSelectType<T> = (record, recordKey) => { const OnRowSelectKeys = getTableRowSelection(selectedRowKeys, recordKey); const OnRowSelectRows = getTableRowSelection(selectedRows, record); setSelectRowKeys(OnRowSelectKeys); setSelectedRows(OnRowSelectRows); }; //是否初次加载 const effectCallback = () => { getTableData(); }; isUseDidUpdateEffect ? useDidUpdateEffect(effectCallback, tableDataParams) : useEffect(effectCallback, tableDataParams); return { tablePagination, tableSelect, LoadingAndData, getSearchValue, reloadData, getDeleteNum, onTableRowSelect, tableTotal, searchValue, tableData, setTableData, handleDelete, handleChangeData, handleCrud, recordData, crudType, isShowModal, handleCancel, modalTitle, }; }; export default useGetTable;
type.ts
import { Key } from 'react'; export type changePageType = (current: number, pageSize: number) => void; export type changeSelectType<T> = (selectedRowKeys: React.Key[], selectedRows: T[], info: { type: string }) => void; export type recordType = Record<string, unknown>; export type UseGetTableProps<U = {}> = { url: string; params?: U; isUseDidUpdateEffect?: boolean; type?: number; }; type HttpMethod = 'get' | 'post' | 'put' | 'delete'; export type handleCrudParams = (record: recordType, title: string, crudType: number) => void; export type ChangeDataParams = (url: string, params: recordType, num?: number, method?: HttpMethod) => void; export type handleChangeDataParams = (url: string, params: recordType, method?: HttpMethod) => void; export type onTableRowSelectType<T> = (record: T, recordKey: Key) => void; export type getDeleteNumType = (num?: number) => void;
CustomPagination
import { Table, TablePaginationConfig, PaginationProps, Typography } from 'antd'; const { Link } = Typography; //勾选框的操作 export const CustomRowSelection = { selections: [Table.SELECTION_ALL, Table.SELECTION_INVERT, Table.SELECTION_NONE], preserveSelectedRowKeys: true, }; //页码 export const CustomPageSize = ['10', '25', '50', '100']; //分页 const itemRender: PaginationProps['itemRender'] = (_, type, originalElement) => { const style = { background: '#ffffff', border: '1px solid #ddd', minWidth: 70, borderRadius: 6, height: 32, display: 'block', }; const LinkType = (v: string) => ( <Link style={{ ...style, position: 'relative' }} className="pageLink"> <span style={{ position: 'absolute', top: '50%', transform: 'translate(-50%,-50%)', width: '100%' }}>{v}</span> </Link> ); if (type === 'prev') { return LinkType('上一页'); } if (type === 'next') { return LinkType('下一页'); } return originalElement; }; export type CustomPaginationConfig = (current: number, pageSize: number, total: number) => TablePaginationConfig; export const CustomPagination: CustomPaginationConfig = (current, pageSize, total) => { return { itemRender, current, pageSize, total, defaultPageSize: 10, showSizeChanger: true, pageSizeOptions: CustomPageSize, showQuickJumper: true, responsive: true, }; }; export const stopPropagation = (e: React.MouseEvent<HTMLElement, MouseEvent> | undefined) => e?.stopPropagation();
useDidUpdateEffect
import { DependencyList, useEffect, useRef } from 'react'; export const useDidUpdateEffect = (fn: { (): void; (): void; }, inputs: DependencyList | undefined) => { const didMountRef = useRef(false); useEffect(() => { if (didMountRef.current) fn(); else didMountRef.current = true; }, inputs); };
getTableRowSelection
//行选 export const getTableRowSelection = <T>(OnRowSelectKeys: T[], recordKey: T) => { const updatedRowKeys = [...OnRowSelectKeys]; const selectedIndex = updatedRowKeys.indexOf(recordKey); if (selectedIndex >= 0) { updatedRowKeys.splice(selectedIndex, 1); } else { updatedRowKeys.push(recordKey); } return updatedRowKeys; };
axiosData
import { showMessage } from 'common/props/messageProps'; import axios, { AxiosRequestConfig } from 'axios'; import { HttpMethod } from '../table/type'; export const axiosData = async <I>(url: string, params: I & AxiosRequestConfig<I>, method: HttpMethod = 'post') => { try { const { status, data } = await axios[method](url, params); if (status === 200) { return data; } } catch (error) { showMessage('error', (error as Error).message); } };
showMessage
import { message } from 'antd'; //类型 内容 持续时间 export const showMessage = (type: 'success' | 'error' | 'info' | 'warning', content: string, duration = 3): void => { message.open({ type, content, duration, }); }; //未勾选 export const notSelectMessage = () => { showMessage('info', '请选择一条要操作的数据'); };
主要使用useTable_crud.ts 里导出的数据 比如表格的勾选分页,数据和loading,模态的打开状态,初始化数据,增删改查的函数等