欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

EditableProTable组件的使用

程序员文章站 2024-03-01 15:00:28
...

代码样例

import { EditableProTable } from '@ant-design/pro-table';
export default () => {
	    const [position, setPosition] = useState('bottom');
	const TagList = ({ value, onChange }) => {
      const ref = useRef(null);
      const [newTags, setNewTags] = useState([]);
      const [inputValue, setInputValue] = useState('');
      const handleInputChange = (e) => {
        setInputValue(e.target.value);
      };
      const handleInputConfirm = () => {
        let tempsTags = [...(value || [])];
        if (inputValue && tempsTags.filter((tag) => tag.label === inputValue).length === 0) {
          tempsTags = [...tempsTags, { key: `new-${tempsTags.length}`, label: inputValue }];
        }
        onChange(tempsTags);
        setNewTags([]);
        setInputValue('');
      }
      return (
        <Space>
          {(value || []).concat(newTags).map((item) => (
            <Tag key={item.key}>{item.label}</Tag>
          ))}
          <Input
            ref={ref}
            type="text"
            size="small"
            style={{ width: 78 }}
            value={inputValue}
            onChange={handleInputChange}
            onBlur={handleInputConfirm}
            onPressEnter={handleInputConfirm}
          />
        </Space>
      );
    }
      
      
      const columns = [
        {
            title: '敏感数据',
            dataIndex: 'title',
            formItemProps: {
                rules: [
                    {
                        required: true,
                        message: '此项为必填项',
                    },
                ],
            },
            // 第二行不允许编辑
            // editable: (text, record, index) => {
            //     return index !== 1;
            // },
            width: '15%',
        },
        
        {
          title: '数据项',
          key: 'item',
          dataIndex: 'item',
          width:'20%',
          valueType: 'select',
          renderFormItem: (_,{ isEditable, record, recordKey}) => {
            console.log('item----',record, recordKey);
            return <SelList /> 
          },
          render: (_, row) => row.item.map((item) => <><Tag key={item.type.key}>{item.type.label}</Tag>{item.dd.label.map((i) => <Tag key={item.dd.key}>{i}</Tag>)}</>),
          // render: (_, row) => console.log('ran--',row.item),

      },
      {
        title: '测试',
        key: 'test',
        dataIndex: 'test',
        // valueType: 'select',
        renderFormItem: (_,  { isEditable, record, recordKey }) => {
          console.log('record----',record, recordKey);
          return isEditable ? <TagList /> : <Input />;
        },
        render: (_, row) => row.labels.map((item) => <Tag key={item.key}>{item.label}</Tag>),
    },
        
        {
            title: '操作',
            valueType: 'option',
            width: '10%',
            render: (text, record, _, action) => [
                <a key="editable" onClick={() => {
                    console.log('=====action', action);
                    var _a;
                    (_a = action.startEditable) === null || _a === void 0 ? void 0 : _a.call(action, record.id);
                }}>
                    编辑
          </a>,
            ],
        },
    ];
      
      const { Option } = Select;
    const add = () => {
        return {
            id: (Math.random() * 5).toFixed(0),
            decs: '随便'
        }
    }
    const dataArr = record => {

        const newData = [...dataSource];
        const index = newData.findIndex(item => record.id === item.id);
        if (index > -1) {//编辑时候
            const item = newData[index];
            newData.splice(index, 1, { ...item, ...record });

            setDataSource(newData);
        }else{
            if (record.title) {
                newData.push(record);
                console.log('new---',newData)
                setDataSource(newData);
            }else{
                setDataSource(newData);
            }
        }  
    }
      
      
		return (<div>
        <EditableProTable rowKey="id" headerTitle="可编辑表格" 
            recordCreatorProps={{
            position,
            record: add()
            }}
            columns={columns}
            request={(params, sort, filter) => {
                return {
                    data: dataSource,
                    //total: defaultData.length,//这里会默认写死表格总数据,不建议在request限定
                    success: true,
                }
            }}
            // pagination={{
            //     showSizeChanger: true,
            //     showQuickJumper: true,
            //     position: ["bottomCenter"],
            //     size: 'small',
            //     defaultPageSize: 10
            // }}
            value={dataSource}
            editable={{
                editableKeys,
                onSave: async (k, r) => {
                    dataArr(r)
                },
                onChange: setEditableRowKeys,
            }} />
    </div>);
};

代码解读

  • recordCreatorProps

    • 新建一行数据的相关配置

    • recordCreatorProps = {
        // 顶部添加还是末尾添加
        position: 'end',
        // 新增一行的方式,默认是缓存,取消后就会消失
        // 如果设置为 dataSource 会触发 onchange,取消后也不会消失,只能删除
        newRecordType: 'dataSource',
        // 不写 key ,会使用 index 当行 id
        record: {},
        // 按钮的样式设置,可以设置按钮是否显示
        // 这样可以做最大行限制和最小行限制之类的功能
        style: {
          display: 'none',
        },
        // https://ant.design/components/button-cn/#API
        ...antButtonProps,
      };
      
  recordCreatorProps={{
                position,
                record: add()
       }}
       
    // position:设置在上方还是在下方   
    // record:设置添加的值
  • editable

    • 在编辑表格中是否可编辑的,函数的参数和 table 的 render 一样
   editable={{
                    editableKeys,
                    onSave: async (k, r) => {
                        dataArr(r)
                    },
                    onChange: setEditableRowKeys,
                }}
                
    // editableKeys:正在编辑的行,受控属性。 默认 key 会使用 rowKey 的配置,如果没有配置会使用 index,建议使用 rowKey
    // onSave:保存
    // onChange:修改

自定义组件

  • 定义自定义组件
  const TagList = ({ value, onChange }) => {
        const ref = useRef(null);
        const [newTags, setNewTags] = useState([]);
        const [inputValue, setInputValue] = useState('');
        const handleInputChange = (e) => {
          setInputValue(e.target.value);
        };
        const handleInputConfirm = () => {
          let tempsTags = [...(value || [])];
          if (inputValue && tempsTags.filter((tag) => tag.label === inputValue).length === 0) {
            tempsTags = [...tempsTags, { key: `new-${tempsTags.length}`, label: inputValue }];
          }
          onChange(tempsTags);
          setNewTags([]);
          setInputValue('');
        }
        return (
          <Space>
            {(value || []).concat(newTags).map((item) => (
              <Tag key={item.key}>{item.label}</Tag>
            ))}
            <Input
              ref={ref}
              type="text"
              size="small"
              style={{ width: 78 }}
              value={inputValue}
              onChange={handleInputChange}
              onBlur={handleInputConfirm}
              onPressEnter={handleInputConfirm}
            />
          </Space>
        );
      }
  • 调用自定义组件

     {
        title: '标签',
        dataIndex: 'labels',
        width: '40%',
        renderFormItem: () => <TagList />,
        render: (_, row) => row?.labels?.map((item) => <Tag key={item.key}>{item.label}</Tag>),
      },
    
  • 解读

    • 自定义组件必须包含valueonChange,没有 value 将会无法注入值,没有 onChange 会无法修改行数据

    • value?: {
          key: string;
          label: string;
        }[];
      
      onChange?: (
          value: {
            key: string;
            label: string;
          }[],
        )
      
    • Value必须包含key和label