React使用ProComponent建立表單和列表

Karle發表於2024-07-13

ProComponent

ProComponent基於Antd元件庫,進一步封裝,成為滿足企業級開發需求的元件庫。其相容Antd內容的基礎上,對錶單列表等內容進行完善,在建立表單等需求中能夠提供強大的api以及功能集合

Ant Design 定義了基礎的設計規範,對應也提供了大量的基礎元件。但是對於中後臺類應用,我們希望提供更高程度的抽象,提供更上層的設計規範,並且提供相應的元件使得開發者可以快速搭建出高質量的頁面。

在 ProComponents 中我們內建了一系列的設計規範,預設了常用的邏輯。在這個基礎上我們同樣提供了靈活的支援,比如對於 ProTable 來說你也可以把它完全當做 Ant Design 的 Table 來用,對於 ProForm 來說你也可以直接使用 Ant Design 的基礎元件或者你的自定義元件。

使用ProTable建立列表

ProTable透過傳入columns物件陣列,遍歷節點進行元件組合,無需透過模版進行表單元件組合,極大減少程式碼長度,便於管理

構建columns

React使用ProComponent建立表單和列表

//columns陣列構建
//透過使用useMemo,建立快取資料,避免造成重新渲染
const columns: ProFormColumnsType[] = useMemo(
  () => [
    createTableColumnIndex() as any,
    {
      title: '廣告名稱',
      dataIndex: 'advertName',
      formItemProps: {
        rules: [{ required: true }],
      },
    },
    {
      title: '廣告描述',
      dataIndex: 'advertDescribe',
    },
    {
      title: '排序',
      dataIndex: 'sort',
      hideInSearch: true,
      valueType: 'digit',
      formItemProps: { min: 0 },
    },
    {
      title: '釋出狀態',
      dataIndex: 'state',
      hideInForm: true,
      valueEnum: {
        0: {
          text: '未釋出',
          status: 'default',
        },
        1: {
          text: '已釋出',
          status: 'success',
        },
      },
    },
    {
      title: '操作',
      dataIndex: 'btn',
      hideInForm: true,
      hideInSearch: true,
      render: (_: any, record: any) => (
        <Space split={<Divider type="vertical" style={{ margin: 0 }} />}>
          <a>釋出</a>
          <a onClick={() => editorRef.current?.show(record)}>編輯</a>
          <a>詳情</a>
          <Popconfirm
            title={'是否刪除'}
            onConfirm={() => onRemove(record.id)}
          >
            <a style={{ color: 'red' }}>刪除</a>
          </Popconfirm>
        </Space>
      ),
    },
  ],
  [],
);

舉例一個列表頁,columns每一個物件為一豎列

title 表頭 dataIndex 對應值欄位名

透過設定hideInForm hideInTabel hideInSearch,控制當前列是否在表單中,列表中和查詢中顯示

render屬效能夠改變元素在行中的展示,透過返回相應的節點

構建列表

<PageContainer>
  <ProTable
    rowKey={'id'}
    columns={columns as any}
    request={getTableRequest}
    actionRef={actionRef}
    toolbar={{
      menu: {
        type: 'tab',
        activeKey: activeKey,
        items: [
          {
            key: 'tab1',
            label: <span>門戶</span>,
          },
          {
            key: 'tab2',
            label: <span>小程式</span>,
          },
        ],
        onChange: (key) => {
          setActiveKey(key as string);
        },
      },
      actions: [
        <Button
          key="add"
          type="primary"
          icon={<PlusOutlined />}
          onClick={() => editorRef.current?.show()}
        >
          新增
        </Button>,
      ],
    }}
  />
</PageContainer>

rowId 每一列設定一個唯一id進行辨識

columns 傳入定義的columns陣列

request 傳入請求資料返回的promise,此處需要進行資料構建,大概為{content:[],total:100,msg:'***'},具體看文件

actionRef 傳入建立的ref節點,用來控制列表的渲染相關內容const actionRef = useRef<ActionType>()

toolbar 用來定義工具欄,能夠構建不同的內容。此處構建了一個按鈕和tab切換

表單構建

將表單作為子元件,透過父元件(列表頁)控制表單頁ref屬性,進行表單頁的展示與隱藏

export const Index: React.ForwardRefExoticComponent<
  Props & React.RefAttributes<ModalRefObject>
> = forwardRef((props, ref) => {
  const formRef = useRef<ProFormInstance>();
  const [visible, setVisible] = useState<boolean>();
  const [record, setRecord] = useState<any>();

  useImperativeHandle(ref, () => ({
    show: (values: any) => {
      setRecord(values);
      setVisible(true);
    },
  }));

  useEffect(() => {
    if (visible) {
      formRef.current?.resetFields();
      formRef.current?.setFieldsValue(record);
    }
  }, [visible, record]);

  return (
    <>
      ***
    </>
  );
});
  • 子元件利用React.forwardRef()構建元件hook,接受父元件傳入的ref物件,
  • 透過useImperativeHandle()設定ref相應方法
  • 定義visible 和 record 狀態記錄表單展示和表單資料

如果是平常的表單,可以透過<BetaSchemaForm/>進行構建,其columns與ProTable相同,透過每個物件建立表單項

<BetaSchemaForm
  width={600}
  columns={columns as any}
  formRef={formRef}
  layout={'horizontal'}
  layoutType={'ModalForm'}
  labelCol={{ flex: '80px' }}
  open={visible}
  onOpenChange={setVisible}
  title={'表單'}
  onFinish={onSave}
  modalProps={{
    centered: true,
    styles: {
      body: { paddingTop: 30 },
    },
  }}
/>

如果表單複雜,可以透過<ProForm/>既相應ProForm項元件進行構建

<ModalForm
  width={600}
  formRef={formRef}
  layout={'horizontal'}
  labelCol={{ flex: '80px' }}
  open={visible}
  onOpenChange={setVisible}
  title={record ? '編輯廣告' : '新增廣告'}
  onFinish={onSave}
  modalProps={{
    centered: true,
    styles: {
      body: { paddingTop: 30 },
    },
  }}
>
  <ProFormText
    name="advertName"
    label="廣告名稱"
    placeholder="請填寫"
    rules={[{ required: true }]}
  />
  <ProFormUploadButton
    label="影片檔案"
    name="file"
    title=""
    listType="picture-card"
    icon={<PlusOutlined />}
    required={true}
    fileList={fileList}
    fieldProps={{
      multiple: true,
      onRemove: onVideoRemove,
      customRequest: uploadFile,
    }}
  />

  <ProFormText
    name="advertDescribe"
    label="廣告描述"
    placeholder="請填寫"
  />
  <ProFormText
    name="sort"
    label="排序"
    placeholder="請填寫"
    fieldProps={{ style: { width: 150 } }}
  />
</ModalForm>

相關文章