手写可编辑表格

最近有一个需求,要手写可编辑表格,接下来我将针对各功能,各页面,进行详细的描述

* 查看态

 *编辑态

 *添加一行数据

 一.思路

1.整体布局使用form包裹table,table的render,编辑状态下使用input,查看状态下使用text

renderType: edit ? 'input-name' : 'text-name',

*注:编辑状态下,渲染的删除列,是如何实现的?

     1.单独写一个删除列对象

const action = ({ remove, add, len }) => {
  return {
    title: '操作',
    fixed: 'right',
    dataIndex: 'action',
    key: 'action',
    render: (_: any, record: any) => {
      return (
        <>
          <Link
            onClick={() => {
              remove(record.name);
            }}>
            删除
          </Link>
        </>
      );
    },
  };
};

       2.判断,如果是编辑状态下,就使用concat() concat方法用于连接两个或多个数组()

<Form.Item>
                    <Table
                      pagination={false}
                      size={'small'}
                      title={() => props.title}
                      rowKey={'name'}
                      dataSource={fields}
                      columns={cls.concat(props.hideAction ? [] : action({ add, remove, len }))}
                    />
                  </Form.Item>

2.添加、删除、确定实现方式

<Form.List name={props.formName || 'tableForm'}>
          {(fields, { add, remove }) => {
            const len = fields.length;
            return (
              <>
                <div>
                  <Form.Item>
                    <Table
                      pagination={false}
                      size={'small'}
                      title={() => props.title}
                      rowKey={'name'}
                      dataSource={fields}
                      columns={cls.concat(props.hideAction ? [] : action({ add, remove, len }))}
                    />
                  </Form.Item>
                  <Form.Item>
                    {edit && (
                      <div className="basic-information-add-button" onClick={() => add()}>
                        添加一行数据
                      </div>
                    )}
                  </Form.Item>
                </div>
              </>
            );
          }}
        </Form.List>

     1.添加 (建议大家看看ant-design的form里边的form.List)form.List自带add()、move()方法,使用就可以实现添加,删除!方便的很!!

*注:使用add和move方法,都要在form.List之下

        我理解的form.List可以动态的为子组件实现添加(add),删除(move)方法,也可以进行校验

     2.确定(确定就没什么可说的啦,根据自己的业务需求,form.getFieldsValue()拿到数据,然后写逻辑就可以了)

3.数据渲染

   1.首先是查看态:就是table的表格渲染数据,没什么可说的

下面的Foem.Item是查看态,cls是继承来自父组件,下面展示父组件码 

<div className="cip-capability-info-container" style={{ marginTop: 17 }}>
      <Form form={form} name="basic">
        <ListTableForm
          hideAction={!edit}
          edit={edit}
          formName="packageProduct"
          fields={basicData}
          basicData={basicData}
          cls={[
            {
              title: '参数名',
              name: 'name',
              dataIndex: 'name',
              key: 'name',
              renderType: edit ? 'input-name' : 'text-name',
            },
            {
              title: '默认值',
              name: 'value',
              dataIndex: 'value',
              key: 'value',
              renderType: edit ? 'input-value' : 'text-value',
            },
            {
              title: '描述',
              name: 'description',
              dataIndex: 'description',
              key: 'description',
              renderType: edit ? 'input-description' : 'text-description',
            },
          ]}
        />

        <Form.Item>
          <Space>
            {edit ? (
              <>
                <Button onClick={onFinish} type="primary" htmlType="submit">
                  确定
                </Button>
                <Button
                  onClick={() => {
                    setEdit(false);
                  }}>
                  取消
                </Button>
              </>
            ) : (
              <Button
                type="primary"
                onClick={() => {
                  setEdit(true);
                  form.setFieldsValue({ packageProduct: basicData });
                }}>
                编辑
              </Button>
            )}
          </Space>
        </Form.Item>
      </Form>
    </div>

2.子组件数据渲染  *注:子组件的数据,在点击编辑的时候,使用form.setFieldsValue()放进表格里,

const ListTableForm: React.FC<PropsType> = (props: PropsType) => {
  const { edit, basicData } = props;
  const rules = [{ required: true, message: '请填充内容!' }];

  const [cls, setCls] = useState<any[]>([]);

  function renderType(_: any, record: any, index: any, other: any) {
    const { renderType } = other;  //renderType是让编辑态的表格,继承查看态的表格
    switch (renderType) {
      case 'input-name':
        return (
          <Form.Item
            rules={rules}
            name={[record.name, other.name]}
            fieldKey={[record.fieldKey, other.name]}>
            <Input defaultValue={record.name} />
          </Form.Item>
        );
      case 'input-value':
        return (
          <Form.Item
            rules={rules}
            name={[record.name, other.name]}
            fieldKey={[record.fieldKey, other.name]}>
            <Input defaultValue={record.value} />
          </Form.Item>
        );
      case 'input-description':
        return (
          <Form.Item
            rules={rules}
            name={[record.name, other.name]}
            fieldKey={[record.fieldKey, other.name]}>
            <Input defaultValue={record.description} />
          </Form.Item>
        );
      case 'text-name':
        return (
          <Form.Item
            rules={rules}
            name={[record.name, other.name]}
            fieldKey={[record.fieldKey, other.name]}>
            <Text>{record.name}</Text>
          </Form.Item>
        );
      case 'text-value':
        return (
          <Form.Item
            rules={rules}
            name={[record.name, other.name]}
            fieldKey={[record.fieldKey, other.name]}>
            <Text>{record.value}</Text>
          </Form.Item>
        );
      case 'text-description':
        return (
          <Form.Item
            rules={rules}
            name={[record.name, other.name]}
            fieldKey={[record.fieldKey, other.name]}>
            <Text>{record.description}</Text>
          </Form.Item>
        );
      default:
        return (
          <Form.Item shouldUpdate={true}>
            {({ getFieldValue }) => {
              return (getFieldValue(props.formName) || [])?.[index]?.[other?.name];
            }}
          </Form.Item>
        );
    }
  }

  useEffect(() => {
    const _newProps = props.cls.map((item) => {
      const { render, ...resetProps } = item;
      return {
        ...resetProps,
        render: (text: any, record: any, index: any) => renderType(text, record, index, item),
      };
    });
    setCls(_newProps);
  }, [props.cls]);

  return (
    <>
      {edit ? (
        <Form.List name={props.formName || 'tableForm'}>
          {(fields, { add, remove }) => {
            const len = fields.length;
            return (
              <>
                <div>
                  <Form.Item>
                    <Table
                      pagination={false}
                      size={'small'}
                      title={() => props.title}
                      rowKey={'name'}
                      dataSource={fields}
                      columns={cls.concat(props.hideAction ? [] : action({ add, remove, len }))}
                    />
                  </Form.Item>
                  <Form.Item>
                    {edit && (
                      <div className="basic-information-add-button" onClick={() => add()}>
                        添加一行数据
                      </div>
                    )}
                  </Form.Item>
                </div>
              </>
            );
          }}
        </Form.List>
      ) : (
        <Form.Item>
          <Table pagination={false} dataSource={basicData} columns={cls} />
        </Form.Item>
      )}
    </>
  );
};

export default ListTableForm;

好啦 这样就能实现啦 如有疑问 欢迎指教!

问题:1.在新增一条数据的时候,用add()方法,会导致第一排数据出现name:index(index为0,1,2,3,4)

解决办法:add(name:'')

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值