antd中的表格表单+日期选择限制

这篇博客介绍了如何在Ant Design的表格中集成可编辑的输入框和日期选择器,并实现日期选择的限制。通过示例代码展示了如何在表格单元格中嵌入Form.Item和Datepicker组件,同时利用`disabledDate`属性限制日期范围,确保用户只能选择相差不超过7天的日期。此外,还涵盖了表格数据的初始化和提交表单时的数据处理。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

antd中的表格表单+日期限制

经常会遇到这种需求,一个表格中需要有可编辑的input,甚至可能还会有日期组件,而官方的demo中并没有这类案例

表格输入框+日期

Formtable


import { Button, Form, Input, Table } from "antd";
import React, { useEffect } from "react";

import Datepicker from "./Datepicker";

import moment from "moment";

const Formtable = (props) => {
  const [form] = Form.useForm();
  const columns = [
    {
      title: "姓名",
      dataIndex: "name",
      key: "name",
    },
    {
      title: "年龄",
      dataIndex: "age",
      key: "age",
      render: (text, record, index) => {
        return (
          <Form.Item name={["table", index, "age"]}>
            <Input placeholder="请输入年龄" />
          </Form.Item>
        );
      },
    },
    {
      title: "日期",
      dataIndex: "date",
      key: "date",
      render: (text, record, index) => {
        return (
          <Form.Item name={["table", index, "date"]}>
            <Datepicker time={text} form={form} nameDate={index} />
          </Form.Item>
        );
      },
    },
  ];

  useEffect(() => {
    // ## 初始化表格数据(在没有请求到数据前有一行做展示)

    // form.setFieldsValue({
    //   table: [
    //     {
    //       key: "",
    //       name: "",
    //       age: "",
    //       date: "",
    //     },
    //   ],
    // });
    setTimeout(() => {
      // ## 模拟请求后获取的table数据
      form.setFieldsValue({
        table: [
          {
            key: "1",
            name: "胡彦斌",
            age: 32,
            date: [
              moment("2022-01-30", "YYYY-MM-DD"),
              moment("2022-02-01", "YYYY-MM-DD"),
            ],
          },
          {
            key: "2",
            name: "胡彦祖",
            age: 42,
            date: [
              moment("2022-02-01", "YYYY-MM-DD"),
              moment("2022-03-31", "YYYY-MM-DD"),
            ],
          },
        ],
      });
    }, 1000);
  }, []);

  const onFinish = (values) => {
    // ## 点击Submit提交后
    console.log(values);
  };

  return (
    <Form form={form} onFinish={onFinish}>
      <Form.Item name="table" valuePropName="dataSource">
        <Table bordered columns={columns} pagination={false} />
      </Form.Item>
      <Form.Item>
        <Button htmlType="submit" type="primary">
          Submit
        </Button>
      </Form.Item>
    </Form>
  );
};

export default Formtable;



Datepicker

该日期组件进行了选择限制,比如我选择了1月01日,那么结束日期就只能选择1月08日


import { DatePicker } from "antd";
import React, { useState } from "react";

import moment from "moment";

const { RangePicker } = DatePicker;
const Datepicker = ({ time, form, nameDate }) => {
  const [dates, setDates] = useState(time);
  const [value, setValue] = useState(null);
  const disabledDate = (current) => {
    if (!dates) {
      return false;
    }
    const tooLate = dates[0] && current.diff(dates[0], "days") > 7;
    const tooLateTwo = dates[0] && current.diff(dates[0], "days") < 7;
    const tooEarly = dates[1] && dates[1].diff(current, "days") > 7;
    const tooEarlyTwo = dates[1] && dates[1].diff(current, "days") < 7;
    return !!tooEarly || !!tooLate || !!tooLateTwo || !!tooEarlyTwo;
  };
  const onOpenChange = (open) => {
    if (open) {
      setDates([null, null]);
    } else {
      setDates(null);
      // console.log(dates[0].format("YYYY-MM-DD"), "新的数据");
      // ## 重构数据
      const newTime = form.getFieldValue("table").map((tit) => {
        if (Number(tit.key) === nameDate + 1) {
          return {
            ...tit,
            date: [
              moment(dates[0].format("YYYY-MM-DD"), "YYYY-MM-DD"),
              moment(dates[1].format("YYYY-MM-DD"), "YYYY-MM-DD"),
            ],
          };
        } else {
          return { ...tit };
        }
      });
      // ## 将重构的数据应用
      form.setFieldsValue({
        table: newTime,
      });
    }
  };
  return (
    <RangePicker
      value={dates || value}
      disabledDate={disabledDate}
      onCalendarChange={(val) => setDates(val)}
      onChange={(val) => setValue(val)}
      onOpenChange={onOpenChange}
      onBlur={() => console.log("blur has been triggered")}
    />
  );
};
export default Datepicker;


<think>嗯,用户的问题是关于在Ant Design的EditableProTable中使用React Hooks和DatePicker组件实现行编辑和保存的逻辑。首先,我需要回忆一下EditableProTable的用法,它通常用于表格数据的可编辑操作,支持行内编辑和保存。React Hooks的话,应该会用到useState、useEffect这些基础Hook,可能还需要用到自定义Hook来管理状态。 接下来,DatePicker组件在Ant Design中的使用方式,用户可能需要禁用某些日期,比如只能选择今天之前的日期,或者设置默认值。参考引用中的例子,比如引用3提到的disabledDate函数,可以用来限制日期选择范围。还有引用1中提到用setFieldsValue给DatePicker设置默认值,不过这里可能不需要Form表单,而是直接通过state来控制。 然后,用户的问题是关于保存和编辑逻辑的最佳实践。在EditableProTable中,每一行的编辑状态可能需要单独管理,或者在全局状态中统一处理。使用Hooks的话,可以用useState来维护数据源和编辑状态。当用户点击编辑时,触发某个函数进入编辑模式,此时显示DatePicker组件,而不是静态文本。保存时,需要更新数据源,并退出编辑模式。 可能需要考虑的几个步骤: 1. 数据源的状态管理,使用useState来存储表格的数据。 2. 行编辑的触发,通过点击编辑按钮切换编辑模式,记录当前正在编辑的行ID。 3. 在编辑模式下渲染DatePicker组件,并绑定对应的值。 4. 保存时,更新数据源,并关闭编辑模式。 5. 处理日期选择的变化,可能需要一个onChange回调来更新临时状态,直到保存。 另外,EditableProTable可能有自己的API来处理行编辑,比如通过editable属性配置。需要查阅Ant Design的文档,确认是否支持自定义的编辑组件,比如DatePicker。如果支持,可能在render函数中根据编辑状态返回不同的组件。 关于性能优化,可能需要避免不必要的渲染,使用useMemo或useCallback来缓存函数和组件。还有,日期处理库如moment或dayjs,需要正确导入和处理日期对象。 可能遇到的问题包括:如何正确绑定DatePicker的值到行数据,如何处理保存时的数据更新,以及如何同步状态到EditableProTable的数据源。需要确保在保存时,新的日期值被正确更新到数据源中,并触发重新渲染。 另外,参考引用4提到的表单验证策略,可能在保存前需要对输入的日期进行验证,比如是否必填,格式是否正确。这时候可以结合Ant Design的Form验证规则,或者在保存时手动检查值是否有效。 最后,要确保代码结构清晰,逻辑分离,比如将状态管理、事件处理、UI渲染分开处理,便于维护和调试。</think>### 在 Antd EditableProTable 中使用 React Hooks 和 DatePicker 实现行编辑与保存的实践 #### 1. 基础配置与数据初始化 使用 `useState` 管理表格数据,结合 `editableKeys` 控制编辑状态: ```javascript import { useState } from 'react'; import { EditableProTable } from '@ant-design/pro-components'; import { DatePicker } from 'antd'; import moment from 'moment'; const DemoTable = () => { const [dataSource, setDataSource] = useState([ { id: 1, date: moment('2023-01-01'), status: '未提交' } ]); const [editableKeys, setEditableKeys] = useState([]); } ``` #### 2. 日期禁用逻辑实现 通过 `disabledDate` 控制可选日期范围(如禁止选择未来日期)[^3]: ```javascript const disabledDate = (current) => { return current && current > moment().endOf('day'); }; ``` #### 3. 列配置与编辑切换 在列定义中处理编辑状态切换和组件渲染: ```javascript const columns = [ { title: '操作', valueType: 'option', render: (text, record, _, action) => [ <a key="editable" onClick={() => action?.startEditable(record.id)} > 编辑 </a> ] }, { title: '日期', dataIndex: 'date', render: (_, record) => ( editableKeys.includes(record.id) ? <DatePicker disabledDate={disabledDate} value={record.date} onChange={(date) => handleDateChange(date, record.id)} /> : record.date.format('YYYY-MM-DD') ) } ] ``` #### 4. 数据更新与保存逻辑 通过 `onValuesChange` 实现实时保存,或使用保存按钮提交: ```javascript const handleSave = async (rowKey, data) => { setDataSource(dataSource.map(item => item.id === rowKey ? { ...data, status: '已提交' } : item )); setEditableKeys([]); // 可添加API调用 }; <EditableProTable columns={columns} rowKey="id" value={dataSource} onChange={setDataSource} editable={{ editableKeys, onSave: handleSave, onChange: setEditableKeys }} /> ``` #### 5. 状态管理优化建议 - 使用 `useMemo` 缓存列配置避免重复渲染 - 复杂场景可结合 `useReducer` 管理状态变更 - 异步操作时添加加载状态: ```javascript const [loading, setLoading] = useState(false); const handleAsyncSave = async (id) => { setLoading(true); await api.updateRecord(id, data); setLoading(false); } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值