使用antd的table和form封装proForm

472 阅读1分钟

有些情况下,项目中不允许引入procomponents,但是设计图又与pro高度相似,遂自己封装一下更舒服;

"use client"; // nextjs下的客户端声明,不是本框架可以不用关心
import {
  Button,
  Col,
  ConfigProvider,
  Form,
  Input,
  Row,
  Space,
  Table,
} from "antd";
import Icon from "@/components/Icon";
import { RedoOutlined } from "@ant-design/icons";
import clsx from "clsx";
import zhCN from "antd/locale/zh_CN";
import "dayjs/locale/zh-cn";
import dayjs from "dayjs";
import {
  ReactElement,
  JSXElementConstructor,
  ReactNode,
  ReactPortal,
  PromiseLikeOfReactNode,
  useState,
  useEffect,
  useCallback,
} from "react";

export type requestType = { data: any[]; success: boolean; total: number };

dayjs.locale("zh-cn");

type params = Object;

type props = {
  rowkey: string;
  column: {
    hideInsearch?: boolean;
    key?: string;
    dataIndex?: any;
    title:
      | string
      | number
      | boolean
      | ReactElement<any, string | JSXElementConstructor<any>>
      | Iterable<ReactNode>
      | ReactPortal
      | PromiseLikeOfReactNode
      | null
      | undefined;
  }[];
  request: (params: params) => Promise<requestType>;
  params: params;
};

export default function ProTable({ column, request, params, rowkey }: props) {
  const [data, setData] = useState<any>(); // 依赖数据
  const [total, setTotal] = useState<number>(); // 总数
  const [privateParams, setPrivateParams] = useState<any>(params);

  const getData = useCallback(async (_params: params) => {
    const res = await request(_params);
    setData([...res.data]);
    setTotal(res.total);
  }, [request]);

  useEffect(() => {
    if (privateParams) {
      getData(privateParams);
    }
  }, [privateParams,getData]);

  const [form] = Form.useForm();
  return (
    <ConfigProvider locale={zhCN}>
      <Form
        form={form}
        onFinish={(value) => {
          setPrivateParams({ ...value, ...params });
        }}
      >
        <Row gutter={24}>
          {column?.map((itm) => {
            if (!itm.hideInsearch && itm.key !== "option") {
              return (
                <Col span={8} key={itm.dataIndex}>
                  <Form.Item
                    name={itm.dataIndex}
                    label={
                      <span className={clsx("text-sm", "color-[#1D2129]")}>
                        {itm.title}
                      </span>
                    }
                    colon={false}
                  >
                    <Input placeholder="请输入" style={{ borderRadius: 0 }} />
                  </Form.Item>
                </Col>
              );
            }
          })}
          <div style={{ textAlign: "left" }}>
            <Space size="small" className={clsx("ml-2")}>
              <Button
                htmlType="submit"
                type="primary"
                style={{
                  borderRadius: 0,
                  background: "#2852A0",
                  display: "flex",
                  alignItems: "center",
                  fontSize: "14px",
                }}
              >
                <Icon type="icon-kw-fangdajing" />
                <span style={{ fontSize: "14px" }}>查询</span>
              </Button>

              <Button
                key="clear"
                style={{
                  borderRadius: 0,
                  display: "flex",
                  alignItems: "center",
                }}
                onClick={() => {
                  form.resetFields();
                  setPrivateParams({ ...params });
                }}
              >
                <RedoOutlined />
                <span style={{ fontSize: "14px" }}>重置</span>
              </Button>
            </Space>
          </div>
        </Row>
      </Form>
      <Table
        rowKey={rowkey}
        columns={column}
        dataSource={data || []}
        pagination={{
          pageSizeOptions: [10, 20, 50, 100],
          total: total,
          current: privateParams.current || 1,
          pageSize: privateParams.pageSize || 10,
          showTotal: (total) => `共 ${total} 条`,
          showSizeChanger: true,
          showQuickJumper: true,
          onChange(current, pageSize) {
            setPrivateParams((pre: params) => {
              return { ...pre, current, pageSize };
            });
          },
        }}
      />
    </ConfigProvider>
  );
}