用ant.design实现一个form table,实现在table中输入和校验。并且获取table列表值

用ant.design实现一个table表格,实现输入和校验。能够实时获取form值。

table和form

我用了table的所有默认属性,并根据自己实际需要,加了name和renderType;name属性用于指定单元格的form item 的name;renderType属性,用于指定一些常用的特殊的渲染(如常见的价格输入框,复用性高),您可根据自己实际需要添加相应的renderType。若是想自定义显示,可用table自带默认的render。

实现效果如图
在这里插入图片描述
在这里插入图片描述
代码如下

  • ListTableForm.tsx
import React, { useEffect, useState } from "react";
import { Form, Table } from 'antd'
import { MinusCircleOutlined, PlusCircleOutlined } from "@ant-design/icons";
import styles from './style.less'
import InputNumberDev from "../FormItem/InputNumberDev";


interface PropsType {
  formName?: string; // formItem的name
  title?: string; // table的标题
  hideAction?: boolean; //是否隐藏操作,默认显示
  cls: any[] //列属性设置,最重要的
}

const action = ({remove, add, len}) => {
  return {
    title: '操作',
    fixed: 'right',
    dataIndex: 'action',
    key: 'action',
    render: (text, record, index) => {
      return <>
        { (index !== 0 && index !== len) ? <MinusCircleOutlined
          className={ styles.iconButton }
          onClick={ () => {
            remove(record.name);
          } }
        /> : null }
        { index === 0 ? <PlusCircleOutlined
          className={ styles.iconButton }
          onClick={ () => {
            add();
          } }
        /> : null }
      </>
    }
  }
}


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

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

  function renderType(text, record, index, other) {
    const {renderType, point} = other;

    switch ( renderType ) {
      case 'input-number' :
        return <Form.Item
          rules={ rules }
          name={ [record.name, other.name] }
          fieldKey={ [record.fieldKey, other.name] }
        >
          <InputNumberDev point={ point }/>{/*InputNumber的输入组件,您可自定义*/}
        </Form.Item>;
      case 'text' :
      default:
        return <Form.Item
          shouldUpdate={true}
        >
          {({getFieldValue})=>{
            return (getFieldValue(props.formName) || [])?.[index]?.[other?.name]
          }}
        </Form.Item>
    }

  }

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


  return <>
    <Form.List name={ props.formName || 'tableForm' }>
      { (fields, {add, remove}) => {
        const len = fields.length;
        return (
          <div>
            <Table bordered pagination={ false }
                   className={ styles.listTableEdit }
                   size={ "small" }
                   title={ () => props.title }
                   rowKey={"name"}
                   dataSource={ fields }
                   columns={ cls.concat(props.hideAction ? [] : action({add, remove, len})) }/>
          </div>
        );
      } }
    </Form.List>
  </>;

};


export default ListTableForm;

  • form外部调用
<Form
          { ...layout }
          form={ form }
          name="basic"
          initialValues={ {standard: standardStr, packageProduct: [
              {productName: "云南白药1",productType: "(4g,保险子1粒)*6瓶 ",unitPrice: 10},
              {productName: "云南白药2",productType: "(4g,保险子1粒)*8瓶 ",unitPrice: 10},
            ]} }
          onFinish={ (values)=>{
            console.log(values)
          } }
        >

          <Form.Item rules={ requiredRulesConfig }>
            <ListTableForm
              title={ "确认实际供货单价(含税)" }
              hideAction
              formName="packageProduct"
              cls={ [{
                title: '货品名称',
                name: 'productName',
                dataIndex: 'productName',
                renderType: 'text',
              }, {
                title: '货品规格',
                name: 'productType',
                dataIndex: 'productType',
                renderType: 'text',
              }, {
                title: '供货单价(含税)',
                name: 'unitPrice',
                dataIndex: 'productType',
                renderType: 'text',
              }, {
                title: '实际供货单价(含税)',
                name: 'purchasePrice',
                dataIndex: 'purchasePrice',
                point: 4,
                renderType: 'input-number',
              }] }/>
          </Form.Item>
          <Form.Item >
            <Button type="primary" htmlType="submit">
              确定
            </Button>
          </Form.Item>
        </Form>
  • 自定义render
{
title: '自定义title',
name: 'myName',
 dataIndex: 'myName',
 render:(_,record,index,other)=>{
   return <Form.Item
     name={ [record.name, other.name] }
     fieldKey={ [record.fieldKey, other.name] }
   >
     <Input />
   </Form.Item>
 }
}
根据提供的引用内容,ant-design-vue可以通过内置的Form组件和Table组件实现表格内部字段验证功能。具体步骤如下: 1. 在表格中添加需要验证的字段,例如下面的代码中的name和age字段: ```html <a-form :form="form"> <a-form-item label="Name" :rules="[{ required: true, message: 'Please input name' }]"> <a-input v-decorator="['name']" /> </a-form-item> <a-form-item label="Age" :rules="[{ required: true, message: 'Please input age' }]"> <a-input-number v-decorator="['age']" /> </a-form-item> </a-form> <a-table :columns="columns" :dataSource="dataSource" :pagination="false" /> ``` 2. 在表格中添加操作列,例如下面的代码中的操作列包含了编辑和删除按钮: ```html <a-table :columns="columns" :dataSource="dataSource" :pagination="false"> <template #action="text, record"> <a-button @click="edit(record)">Edit</a-button> <a-button @click="delete(record)">Delete</a-button> </template> </a-table> ``` 3. 在编辑操作中打开表单,并将当前行的数据绑定到表单中: ```javascript edit(record) { this.form.setFieldsValue(record); this.editingKey = record.key; } ``` 4. 在表单中添加保存按钮,并在点击保存按钮时进行表单验证和数据更新: ```html <a-form :form="form"> <a-form-item label="Name" :rules="[{ required: true, message: 'Please input name' }]"> <a-input v-decorator="['name']" /> </a-form-item> <a-form-item label="Age" :rules="[{ required: true, message: 'Please input age' }]"> <a-input-number v-decorator="['age']" /> </a-form-item> <a-form-item> <a-button type="primary" @click="save">Save</a-button> </a-form-item> </a-form> ``` ```javascript save() { this.form.validateFields((err, values) => { if (!err) { const newData = [...this.dataSource]; const index = newData.findIndex((item) => this.editingKey === item.key); if (index > -1) { const item = newData[index]; newData.splice(index, 1, { ...item, ...values }); this.dataSource = newData; this.editingKey = ''; } else { newData.push(values); this.dataSource = newData; this.editingKey = ''; } } }); } ```
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值