当前位置: 首页 > 工具软件 > x-editable > 使用案例 >

EditableProTable组件的使用

谷梁向荣
2023-12-01

代码样例

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

 类似资料: