项目中Ant Design Pro业务问题解决方案

1、ProTable实现多选+反显+筛选项多级关联选择

import { forwardRef, useImperativeHandle, useEffect, useRef, useReducer } from 'react';
import { Drawer, Space, Button, message } from 'antd';
import { ProTable, ProColumns, ProFormText, ProFormSelect } from '@ant-design/pro-components';
import type { FormInstance } from 'antd';

interface StateType {
    visible?: boolean; // 是否显示
    promotionList: any[];
    pageSize?: number; // 一页几条
    total?: number; // 总页数
    selectedRowKeys: any[];
    selectedRows: any[];
    oneList: any[]; //一级demo列表
    twoList: any[]; //二级demo列表
    threeList: any[]; //三级demo列表
}
interface ParamsType {
    pageSize?: number;
    current?: number;
    keyword?: string;
    pageNo?: number;
}

interface PropsType {
    callback?: (selectedRows: any) => void; // 回调函数
}

export type DemoRef = {
    show: (list: any[]) => void; // 显示抽屉
};

const DemoDrawer = forwardRef<DemoRef, PropsType>((props, ref) => {
    const { callback } = props;
    const initState: StateType = {
        visible: false,
        pageSize: 10,
        total: 0,
        selectedRowKeys: [],
        selectedRows: [],
        oneList: [],
        twoList: [],
        threeList: [],
    };
    const [state, dispatch] = useReducer((oldState, action) => {
        return { ...oldState, ...action };
    }, initState);
    const formRef = useRef<FormInstance>();

    useImperativeHandle(ref, () => ({
        show: (list) => {
            if (list && list.length > 0) {
                const keys = list.map((item) => item.rowKey);
                dispatch({
                    visible: true,
                    selectedRows: list,
                    selectedRowKeys: keys,
                });
                return;
            }
            dispatch({
                visible: true,
            });
        },
    }));

    // 获取列表
    const onQueryList = async (params: ParamsType) => {
        try {
            const res: any = await getDemoList({
                ...params,
            });
            const total = res?.totalRow || 0;
            const list = res?.dataList?.map((item: any) => {
                return { ...item, rowKey: `${item.demoK1}-${item.demoK2}` };
            });
            dispatch({
                pageSize: params.pageSize,
                total,
            });
            return {
                success: true,
                data: list,
                total,
                ...params,
            };
        } catch (err) {
            console.log('获取列表接口异常', err);
            return {};
        }
    };
    // 处理关闭事件
    const onClose = () => {
        dispatch(initState);
    };

    //获取一级列表
    const getPinLeiList = async ({ id, getType }: any) => {
        const params: any = {};
        if (id && getType) {
            params.id = id;
        }
        const res = await getPinLei(params);
        if (res) {
            const list = res.map((item: any) => ({
                label: item.name,
                value: item.id,
            }));
            if (!getType) {
                dispatch({
                    oneList: list,
                });
            }
            if (getType === 'getTwo') {
                dispatch({
                    twoList: list,
                });
            }
            if (getType === 'getThress') {
                dispatch({
                    threeList: list,
                });
            }
        }
    };
    useEffect(() => {
        if (state?.visible) {
            getPinLeiList({});
        }
    }, [state?.visible]);
    // 处理提交事件
    const onSubmit = async () => {
        const { selectedRows } = state;
        if (selectedRows.length === 0) {
            onClose();
            return;
        }
        //数据校验
        if (selectedRows.length < 2) {
            message.error('至少选择2个demo');
            return;
        }
        if (selectedRows.length > 10) {
            message.error('至多选择10个demo');
            return;
        }
        callback?.(state.selectedRows);
        onClose();
    };
    const columns: ProColumns<any>[] = [
        {
            dataIndex: 'demoName',
            title: 'demo名称',
            renderFormItem: () => {
                return <ProFormText />;
            },
        },
        {
            dataIndex: 'one',
            title: '一级',
            hideInTable: true,
            renderFormItem: () => {
                return <ProFormSelect options={state?.oneList} showSearch />;
            },
        },
        {
            dataIndex: 'two',
            title: '二级',
            hideInTable: true,
            renderFormItem: () => {
                return <ProFormSelect options={state?.twoList} showSearch />;
            },
        },
        {
            dataIndex: 'three',
            title: '三级',
            hideInTable: true,
            renderFormItem: () => {
                return <ProFormSelect options={state?.threeList} showSearch />;
            },
        },
    ];
    const onFieldsChange = (changedFields: any[]) => {
        const touched = changedFields?.[0];
        const field = touched?.name?.[0];
        if (field === 'one') {
            if (touched.value) {
                //选择了一级,获取二级
                getPinLeiList({ id: touched.value, getType: 'getTwo' });
            }
            //清空二级、三级,同时清空form值
            dispatch({
                twoList: [],
                threeList: [],
            });
            formRef.current?.setFieldsValue({
                two: undefined,
                three: undefined,
            });
        }
        if (field === 'two') {
            if (touched.value) {
                //选择了二级,获取三级
                getPinLeiList({
                    id: touched.value,
                    getType: 'getThress',
                });
            }
            //情况三级,同时清空form值
            dispatch({
                threeList: [],
            });
            formRef.current?.setFieldsValue({
                three: undefined,
            });
        }
    };

    return (
        <Drawer
            destroyOnClose
            title={'添加demo'}
            placement="right"
            width="80%"
            closable
            maskClosable={false}
            onClose={onClose}
            open={state?.visible}
            footer={
                <Space>
                    <Button onClick={onClose}>取消</Button>
                    <Button
                        type="primary"
                        onClick={onSubmit}
                        disabled={state.selectedRows.length < 1}
                    >
                        确认
                    </Button>
                </Space>
            }
        >
            <ProTable
                rowKey="rowKey"
                options={false}
                columns={columns}
                pagination={{
                    pageSizeOptions: ['10', '20', '50'],
                    pageSize: state.pageSize,
                    total: state.total,
                    showSizeChanger: true,
                }}
                search={{
                    defaultCollapsed: false,
                    span: 8,
                }}
                form={{ onFieldsChange }}
                formRef={formRef}
                rowSelection={{
                    preserveSelectedRowKeys: true,
                    type: 'checkbox',
                    selectedRowKeys: state.selectedRowKeys,
                    onChange: (selectedRowKeys, selectedRows) => {
                        //反显问题
                        const rowsList = selectedRows?.map((item, index) => {
                            if (item) {
                                return item;
                            } else {
                                const rowKey = selectedRowKeys[index];
                                const row = state.selectedRows.filter(
                                    (i: any) => i.rowKey === rowKey,
                                )[0];
                                return row;
                            }
                        });
                        dispatch({ selectedRowKeys, selectedRows: rowsList });
                    },
                    getCheckboxProps: (record: any) => ({
                        disabled: record.type === 'demo',
                    }),
                }}
                request={(params: ParamsType) => {
                    const newParams = {
                        currentPage: params.current,
                        pageSize: params.pageSize,
                        ...params,
                    };
                    delete newParams.current;
                    return onQueryList(newParams);
                }}
            />
        </Drawer>
    );
});

export default DemoDrawer;

反显时候onChange: (selectedRowKeys, selectedRows)中selectedRows可能会有undefined,需要把对应数据还原回去。

form={{ onFieldsChange }}实现级联选择。

2、Form表单项值前后去空格

<ProFormText
  name="demo"
  label="demo名称"
  getValueFromEvent={(e) => {
    return e?.target?.value?.trim();
  }}
  fieldProps={{ maxLength: 12 }}
  rules={[{ required: true, message: "请输入demo名称" }]}
/>;

3  ProTable搜索提交表单值前后去空格

<ProTable
  beforeSearchSubmit={(params) => {
    for (const item of Object.keys(params)) {
      if (typeof params[item] === "string") {
        params[item] = params[item].trim();
      }
    }
    return params;
  }}
/>

推广一下自己开发的微信小程序,有兴趣的朋友可以玩一玩

  • 8
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值