【Ant Design】Form.Item创建自定义表单

一、概述

Antd是一个非常强大的UI组件库,里面的Form表单组件也基本能满足我们大多数场景。但是也有需要自定义表单的场景。

  • Vue2里我们使用v-model,结合子组件的model属性,来实现自定义组件的双向绑定。

  • Vue3里我们使用v-model,结合子组件的update:modelValue来实现同样功能。

  • 到了React+Antd中,我们采用引用父组件默认传入onChange事件,子组件调用来实现。

二、开发实现

1、代码

父组件代码:

tsx 复制代码
import { Button, Space, Form, Input, Radio, Switch } from "antd";
import MyBtns from "./components/myBtns";
import { useState, useEffect } from "react";

function Index() {
    const [form] = Form.useForm();
    const [formData, setFormData] = useState<Object>({});

    const layout = {
        name: "myFrom",
        autoComplete: "off",
        labelCol: {
            span: 3,
        },
        wrapperCol: {
            span: 21,
        }
    };
    const initData = {
        title: "IT飞牛的自定义表单",
        item1: "选项-2",
    };

    const onFinish = async (values: Object) => {
        //提交数据
        //...
    }
    const onReset = () => {
        form.resetFields();
    };
    useEffect(() => {
        setFormData(initData);
    }, [])

    return <div>
        {JSON.stringify(formData)}
        <Form
            onFinish={onFinish}
            onValuesChange={(changedValues, allValues) => { setFormData(allValues) }}
            form={form}
            labelAlign="right"
            initialValues={initData}
            style={{
                "marginTop": "50px"
            }}
            {...layout}
        >
            <Form.Item name="title" label="标题">
                <Input />
            </Form.Item>
            <Form.Item name="item1" label="自定义项">
                <MyBtns />
            </Form.Item>
            <Form.Item wrapperCol={{ offset: 3, span: 21 }}>
                <Space size="middle">
                    <Button htmlType="button" onClick={onReset}>
                        取消
                    </Button>
                    <Button type="primary" htmlType="submit">
                        提交
                    </Button>
                </Space>
            </Form.Item>
        </Form>
    </div >
}

export default Index;

子组件(myBtns.tsx)代码:

tsx 复制代码
import { Button, Space } from "antd";

const myBtns = (props: any) => {
    const { value, onChange } = props //value 是form表单中"name"对应的字段值

    const onSelected = (val: string) => {
        onChange(val)
    }

    const getTypeClass = (val: string) => {
        return value == val ? "default" : "dashed";
    }

    return <Space>
        <Button type={getTypeClass("选项1")} onClick={() => onSelected("选项1")}>选项1</Button>
        <Button type={getTypeClass("选项2")} onClick={() => onSelected("选项2")}>选项2</Button>
        <Button type={getTypeClass("选项3")} onClick={() => onSelected("选项3")}>选项3</Button>
    </Space>
}

export default myBtns;

2、最终效果

可以看到,表单中有两个选项,第一个是Input组件,第二个是自定义组件MyBtns,已经实现数据的事实更新。

3、原理

Form.Item 在渲染时会注入 valueonChange 事件给子元素。

  • value:form.item对应的name属性的值,可用作默认值以及返显
  • onChange:用于监听value元素值的变化,并将其传给form.item使其可以通过相关api获得其值

注意:当你的字段组件被包裹时属性将无法传递。所以以下代码是不会生效的:

tsx 复制代码
<Form.Item name="input">
  <div>
    <h3>I am a wrapped Input</h3>
    <Input />
  </div>
</Form.Item>
相关推荐
tech_zjf20 分钟前
当 AI 把 Next.js Route 越写越快:我为什么做了 next-route-kit
前端·后端
常宇佳23 分钟前
vue3 @代指src路径设置
前端·typescript·vue
砚凝霜39 分钟前
软考网络工程师|案例分析:Eth‑Trunk 链路聚合、iStack 堆叠、CSS 集群核心考点总结
前端·css·网络
二级小助手1 小时前
二级Web前端选择题高频真题20道与考场避坑笔记
javascript·css3·html5·web前端·计算机二级·二级web·web真题
珐恩AI-人工智能1 小时前
大模型意图召回偏差分析:GEO如何解决“有收录却不触发问答曝光”的难题
大数据·前端·人工智能·html·流量运营·geo优化
程序员老赵1 小时前
Docker 部署禅道 ZenTao:轻松搭建研发项目管理平台
前端·后端·github
前端小卡拉1 小时前
用了大半年 AI 编程工具,我才搞懂 Skill 到底是什么
前端·javascript
hunterandroid1 小时前
[鸿蒙从零到一] HarmonyOS 单元测试与 UI 自动化测试实战:从代码质量到用户体验的全链路保障
前端
郭邯2 小时前
用 Intl.DateTimeFormat 手写一个时区转换器,顺便聊聊我和 AI 结对编程的日常
前端·javascript
阿奇__2 小时前
微前端、iframe与Auth Code技术方案对比
前端