I. Descripción general
Antd es una biblioteca de componentes de interfaz de usuario muy poderosa, y Form
los componentes de formulario que contiene básicamente pueden cumplir con la mayoría de nuestros escenarios. Pero también hay escenarios en los que se requieren formularios personalizados.
-
Vue2
Aquí usamosv-model
, combinado con las propiedades de los subcomponentesmodel
, para implementar el enlace bidireccional de componentes personalizados. -
Vue3
Aquí usamosv-model
, combinado con subcomponentesupdate:modelValue
para lograr la misma función. -
En el medio
React+Antd
, usamos elonChange
evento entrante predeterminado al que hace referencia el componente principal y lo llamamos por el componente secundario.
2. Desarrollo e implementación
1. Código
Código del componente principal:
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;
Código del subcomponente (myBtns.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. Efecto final
Como puede ver, hay dos opciones en el formulario, la primera es Input
un componente y la segunda es un componente personalizado MyBtns
, que ha implementado la actualización objetiva de los datos.
3. Principio
Form.Item
value
Los eventos se inyectarán en elementos secundarios al renderizar onChange
.
- valor: el valor del atributo
form.item
correspondientename
, que se puede utilizar como valor predeterminado y visualización de retorno. - onChange: se utiliza para monitorear
value
los cambios en los valores de los elementos y transmitirlosform.item
para que sus valores se puedan obtener a través de las API relevantes.
Nota: Las propiedades no se pasarán cuando se ajuste el componente de campo. Entonces el siguiente código no tendrá efecto:
<Form.Item name="input">
<div>
<h3>I am a wrapped Input</h3>
<Input />
</div>
</Form.Item>