antd Form表单实践模板(Form.useForm)
定制一个Form表单模板,主要支持Form.List、Form.Item之间联动,快速进入开发
表单结构如下:
- 修改type时重置assetTypeName以及details
- frequencyParam的options监听frequency的值的变化,如果frequency的值变化了,重置frequencyParam的值,同时 frequencyParam的options跟着变动
- details的每一项支持新增/删除
- items的每一项支持新增/删除
- type
- assetTypeName
- details
- name
- frequency
- frequencyParam
- items
- title
- content
- attachments1
- attachments2
import React, { useEffect } from 'react'
import { message, Form, Select, Button, Input, Card, Row, Col, Modal } from 'antd'
import { MinusCircleOutlined, PlusOutlined } from '@ant-design/icons'
import { Upload } from '@/components'const Index = ({ data }: { data: any }) => {const [form] = Form.useForm()const onFinishFailed = (errorInfo: any) => {console.log('Failed:', errorInfo)}useEffect(() => {pageInit()}, [])const pageInit = async () => {// ...}const onFinish = (values: any) => {const params = {// ...}const promise = data.code ? dispatch.xxx.编辑接口 : dispatch.xxx.创建接口promise(params).then((res) => {if (res.code === 200) {message.success('操作成功')}})}return (<Formform={form}name="basic"labelCol={{ span: 4 }}wrapperCol={{ span: 20 }}onFinish={onFinish}onFinishFailed={onFinishFailed}autoComplete="off"><Form.Itemlabel={'xxx'}name={'type'}rules={[{ required: true, message: '请选择xxx' }]}wrapperCol={{ span: 12 }}><Selectplaceholder="请选择"optionFilterProp="label"showSearchoptions={[]}onChange={(e) => {form.setFieldsValue({assetTypeName: undefined,details: [],})}}/></Form.Item><Form.Itemlabel={'名称'}name={'assetTypeName'}rules={[{ required: true, message: '请输入名称' }]}wrapperCol={{ span: 12 }}><Input placeholder="请输入名称" /></Form.Item>{<><Card title="详情"><Form.List name="details">{(details) => (<>{details?.map?.((field) => (<React.Fragment key={field.key}><Row gutter={24}><Col span={8}><Form.Item{...field}labelCol={{ span: 9 }}wrapperCol={{ span: 14 }}label="名称"name={[field.name, 'name']}rules={[{ required: true, message: '请输入名称' }]}><Input placeholder="请输入名称" /></Form.Item></Col><Col span={8}><Form.Item{...field}labelCol={{ span: 9 }}wrapperCol={{ span: 14 }}label="频次"name={[field.name, 'frequency']}rules={[{ required: true, message: '请选择频次' }]}><SelectshowSearchoptionFilterProp="label"style={{ width: '100%' }}placeholder="请选择频次"options={[]}onChange={(e) => {form.setFieldValue(['details', field.name, 'frequencyParam'],undefined,)}}/></Form.Item></Col><Col span={8}><Form.Item noStyle shouldUpdate>{({ getFieldValue }) => {const frequency = getFieldValue(['details', field.name, 'frequency'])if (frequency && frequency !== 1) {return (<Form.Item{...field}labelCol={{ span: 9 }}wrapperCol={{ span: 14 }}label="维保频次"name={[field.name, 'frequencyParam']}rules={[{ required: true, message: '请选择维保频次' }]}><Selectmode="multiple"showSearchoptionFilterProp="label"style={{ width: '100%' }}placeholder="请选择维保频次"options={frequency === 2 ? WeekOptions : DaysOptions}/></Form.Item>)}return null}}</Form.Item></Col></Row><Form.List name={[field.name, 'items']}>{(items, { add, remove }) => (<>{items.map((field2, itemsIndex) => (<React.Fragment key={itemsIndex}><Row gutter={24}><Col span={12}><Form.ItemlabelCol={{ span: 7 }}wrapperCol={{ span: 16 }}label="标题"name={[field2.name, 'title']}rules={[{ required: true, message: '请输入标题' }]}><Input placeholder="请输入标题" maxLength={200} /></Form.Item></Col><Col span={6}><MinusCircleOutlinedonClick={() => {Modal.confirm({title: '是否需要删除该内容?',okText: '确定',okType: 'danger',cancelText: '取消',onOk() {remove(field2.name)},})}}/></Col></Row><Form.ItemlabelCol={{ span: 3.5 }}wrapperCol={{ span: 12 }}label="内容"name={[field2.name, 'content']}rules={[{ required: true, message: '请输入内容' }]}><Input.TextArea placeholder="请输入内容" maxLength={2000} /></Form.Item><Form.ItemlabelCol={{ span: 4 }}wrapperCol={{ span: 12 }}label="上传示意图"name={[field2.name, 'attachments1']}rules={[{ required: true, message: '请选择上传示意图' }]}><UploadbeforeUpload={() => false}text={'点击上传'}multiple={true}accept=".jpg,.jpeg,.png"maxCount={25}/></Form.Item><Form.ItemlabelCol={{ span: 4 }}wrapperCol={{ span: 12 }}label="上传维保视频"name={[field2.name, 'attachments2']}// rules={[{ required: true, message: '请上传维保视频' }]}><UploadbeforeUpload={() => false}text={'点击上传'}multiple={true}accept="video/mp4"maxCount={3}/></Form.Item></React.Fragment>))}<Form.Item><Buttontype="dashed"onClick={() => add()}blockicon={<PlusOutlined />}>添加内容</Button></Form.Item></>)}</Form.List></React.Fragment>))}</>)}</Form.List></Card></>}<Form.Item wrapperCol={{ offset: 8, span: 16 }}><Button type="primary" htmlType="submit" style={{ marginRight: 8 }}>确定</Button><Button type="default">取消</Button></Form.Item></Form>)
}
export default Index