用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>
 }
}
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
好的,以下是使用 Ant Design Vue Table 组件实现一列有三个可编辑可新增的代码示例: ```vue <template> <a-table :columns="columns" :dataSource="dataSource" :rowKey="record.id"> <template #name="record" #index="index"> <a-form-item> <a-input-number :value="record.a" :min="0" @change="handleFieldChange(index, 'a', $event)" /> </a-form-item> <a-form-item> <a-input-number :value="record.b" :min="0" @change="handleFieldChange(index, 'b', $event)" /> </a-form-item> <a-form-item> <a-input-number :value="record.c" :min="0" @change="handleFieldChange(index, 'c', $event)" /> </a-form-item> </template> </a-table> </template> <script> import { ref } from 'vue'; import { Table, InputNumber, Form, FormItem } from 'ant-design-vue'; export default { components: { Table, InputNumber, Form, FormItem, }, setup() { const dataSource = ref([ { id: 1, a: 1, b: 2, c: 3, }, { id: 2, a: 4, b: 5, c: 6, }, ]); const columns = [ { title: 'A', dataIndex: 'a', editable: true, }, { title: 'B', dataIndex: 'b', editable: true, }, { title: 'C', dataIndex: 'c', editable: true, }, ]; const handleFieldChange = (index, field, value) => { const newData = [...dataSource.value]; newData[index][field] = value; dataSource.value = newData; }; return { dataSource, columns, handleFieldChange, }; }, }; </script> ``` 在上述代码,我们使用了 Ant Design Vue Table 组件来展示数据,同时将每一列的可编辑属性设置为 true,以实现单元格编辑功能。在模板,我们使用了插槽来自定义每行数据的展示方式,通过 a-form-item 和 a-input-number 组件来实现单元格的编辑及新增功能。在 setup 方法,我们使用了 ref 来声明了一个名为 dataSource 的响应式变量,并初始化了两条数据;同时声明了一个名为 columns 的变量,用于配置表格的列信息;最后声明了一个名为 handleFieldChange 的方法,用于处理单元格的变化事件。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值