pro-components icon indicating copy to clipboard operation
pro-components copied to clipboard

🧐[问题] 自定义的ProFormItem不支持grid属性?

Open GeSnowBoy opened this issue 2 years ago • 6 comments

🧐 问题描述

我自定义了一个ProFormItem组件,但是不能适配grid属性.

如下图, 红圈中的部分明显没有左右平分宽度. image 对应的dom也没被 col类包裹. image 仿写的ProFormUploadButton 组件, 官方的就可以左右平分. 我的就不行. 麻烦指点下怎么定义一个ProFormItem组件??!! 仿写代码仓库: https://github.com/ant-design/pro-components/blob/master/packages/form/src/components/UploadButton/index.tsx

💻 示例代码

// 自定义一个组件,仿照 ProFormUploadButton 组件的写法
import { createField } from "@ant-design/pro-form/lib/BaseForm";
const ImageUpload = () => {
  return "你好世界";
};
const ProFormImage = createField<any>(ImageUpload, {});
export default ProFormImage;

GeSnowBoy avatar Feb 28 '23 18:02 GeSnowBoy

TAutomatically replying with ChatGPT can be attempted, but it cannot be guaranteed to be completely accurate and may not fully address all issues. Please feel free to reply if you have any further questions or concerns. 此回复基于 ChatGPT 自动生成,可以尝试下方案,官方员会在一定时间后继续继续处理。

🌈 解决方案

从你提供的代码看, 单从createField后面没有传参数来看, 我们可以大概猜到你自定义组件的一些情况.

这里给你一些思路, 你可以尝试在自定义ProFormItem组件上加上Col标签进行包裹,这样就可以适配grid属性了.同时, 可以给Col设置span属性, 让它更好的配合Antd的响应式栅格体系.

示例代码:

import React from 'react';
import { Col, FormControlProps } from 'antd';
import { FieldProps } from '@ant-design/pro-field';
import { ProFormItem } from '@ant-design/pro-form';
import ProFormImage from './ProFormImage'; // 引入自定义组件 

const ProFormImageUploadButton: React.FC<FieldProps & FormControlProps> = (props) => {
   const {
      proFieldProps, label, renderFormItem, mode, value, formItemProps, rules,
      readonly: propsReadonly, ...restProps
   } = props; 
   const readonly = mode === 'read' || propsReadonly;
   
   // 将组件包裹在Col标签中
   const node = <ProFormImage {...restProps} />;
   const colProps = { xxl: 6, lg: 8, md: 12, sm: 24, ...proFieldProps };
   return (
      <ProFormItem
         {...formItemProps}
         label={label}
         rules={rules}
         readonly={readonly}
         fieldProps={{ ...restProps, ...formItemProps?.fieldProps }}
         isDefaultRender={false}
         render={renderFormItem}
      >
         <Col {...colProps}>{node}</Col>
      </ProFormItem>
   );
};

export default ProFormImageUploadButton;

📚 相关文档

chenshuai2144 avatar Mar 06 '23 09:03 chenshuai2144

很奇怪为啥官方的组件 ProFormUploadButton 可以左右平分. 我看组件库中使用的也是 import { createField } from "@ant-design/pro-form/lib/BaseForm"; 使用 createField 创建的呀

GeSnowBoy avatar Mar 06 '23 10:03 GeSnowBoy

TAutomatically replying with ChatGPT can be attempted, but it cannot be guaranteed to be completely accurate and may not fully address all issues. Please feel free to reply if you have any further questions or concerns. 此回复基于 ChatGPT 自动生成,可以尝试下方案,官方员会在一定时间后继续继续处理。

很好的问题。使用createField是可以创建自定义表单项(FormItem)的,但是这种方式创建出来的表单项(FormItem),会导致ProForm无法渲染出默认的 标题、描述、错误信息 信息.

如果你在 ProForm 中使用官方的 ProFormUploadButton ,它是不使用 createField 创建的,而是直接用 React.forwardRef 返回了一个 React.FC,直接标记了 ProFormItem.defaultProps,从而保留 ProFormItem 的默认渲染。 如果你希望你的自定义组件在表单中支持默认的渲染逻辑, 可以尝试模仿官方的写法:

import React from 'react';
import { Upload } from 'antd';
import type { UploadProps } from 'antd/lib/upload';
import { ProFormUploadButton } from '@ant-design/pro-form';
import type { ProFormItemProps } from '@ant-design/pro-form/lib/components/FormItem';
import type { FormItemProps } from 'antd/lib/form';

declare type ProFormUploadButtonProps = ProFormItemProps<UploadProps> & {
  formItemProps?: FormItemProps;
};

const ProFormUploadButtonWithDefault: React.ForwardRefRenderFunction<any, ProFormUploadButtonProps> = (
  {
    fieldProps,
    children,
    proFieldProps,
    defaultFileList,
    ...restProps
  }: ProFormUploadButtonProps,
  ref,
) => {
  return (
    <ProFormUploadButton
      fieldProps={fieldProps}
      proFieldProps={proFieldProps}
      request={() => Promise.resolve({ id: '123' })}
      defaultFileList={defaultFileList}
      {...restProps}
      ref={ref}
    >
      {children || (
        <Upload name="logo" listType="picture-card">
            点击上传
        </Upload>)}
    </ProFormUploadButton>
  );
};

export default React.forwardRef(ProFormUploadButtonWithDefault);

在这个示例代码中,我们通过React.forwardRef将 ProFormUploadButtonWithDefault 组件暴露为Ref,提供更多的使用场景,同时保留ProFormItem的默认渲染.

希望这个解决方案可以帮助到你QAQ

chenshuai2144 avatar Mar 07 '23 02:03 chenshuai2144

可能是antd5 的问题,你试着升级下试试?

chenshuai2144 avatar Mar 08 '23 08:03 chenshuai2144

请问ProformItem和Proform.Item有什么区别,文档没搜到

LittleChives avatar Jun 28 '23 16:06 LittleChives

image 确实很奇怪,文档中写ProFormText 是 FormItem + Input 的产物,但是ProFormItem却不支持grid的属性colProps,ProFormText却是支持的 @chenshuai2144

MaZhaolin avatar Jan 10 '24 06:01 MaZhaolin