React hook+AntD pro实现Form表单的二次封装
React hook+AntD pro实现Form表单的二次封装
- 封装Form表单
- 1、在src/types下新建 antd/form/index.ts,进行Form表的配置、数据等类型的限制
- 2、在 根目录/components 下新建 BaseForm/index.tsx文件
- 3、在BaseForm/createFormIpt.tsx中,抽取对不同类型的表单元素渲染
- 4、在src/pages/PublishArticle/下,新建驱动表单的数据文件data.ts
- 5、在src/pages/PublishArticle/下,新建使用二次封装的Form组件的父组件index.ts
封装Form表单
关键hooks API: useImperativeHandle、useRef,高阶组件: forwardRef,
1、在src/types下新建 antd/form/index.ts,进行Form表的配置、数据等类型的限制
import React, { ReactNode } from 'react';
import { IButton } from '@/types/antd/button';
// @ts-ignore
import { FilterFunc, GetFieldsValueConfig } from 'rc-field-form/es/interface';type RadioGroupOption = {buttonStyle?: 'outline' | 'solid';name?: string;options?: any[];optionType?: 'default' | 'button',size?: 'large' | 'middle' | 'small',
}type SelectOptions = {mode?: 'multiple' | 'tags';options?: any[];
}
export type FormOptions = {// 表单名称,会作为表单字段 id 前缀使用name: string;labelCol?: number;wrapperCol?: number;autoComplete?: string;// label 是否显示冒号colon?: boolean;// label 标签的文本对齐方式labelAlign?: 'right' | 'left';// 表单布局layout?: 'horizontal' | 'vertical' | 'inline';// 设置字段组件的尺寸(仅限 antd 组件)size?: 'small' | 'middle' | 'large';// initialValues?: {[index: string]: any}
}export type FormItemOptions = {// 是否显示 label 后面的冒号colon?: boolean;// label 标签的文本label?: ReactNode | string;placeholder?: string;name: string; // use is key// 标签文本对齐方式labelAlign?: 'left' | 'right';labelCol?: number;wrapperCol?: number;noStyle?: boolean;required?: boolean;// 设置防抖,延迟毫秒数后进行校验validateDebounce?: number;// 设置字段校验的时机 : onChangevalidateTrigger?: string | string[];// input 图标prefix?: React.ReactElement;formItemType: string;rules?: {[index: string]: string | boolean}[];formButtons?: IButton[],rows?: number;allowClear?: boolean;selectOptions?: SelectOptions;radioOptions?: RadioGroupOption;
}export interface IFormProps {formOptions: FormOptions;formValue: {[index: string]: any};formItemOptions: FormItemOptions[];emitSubmit?: (formData: any) => void;
}// SystemForm 组件暴露的数据结构
export interface IFormCompExportData {getFieldsValue: (() => any) & ((nameList: (true | any[]), filterFunc?: (FilterFunc | undefined)) => any) & ((config: GetFieldsValueConfig) => any)
}
2、在 根目录/components 下新建 BaseForm/index.tsx文件
子组件:Form的二次封装组件
import React, { forwardRef, useImperativeHandle } from 'react';
import { IFormCompExportData, IFormProps } from '@/types/antd/form';
import createFormIpt from './createFormIpt';
import { Form } from 'antd';const SystemForm = (props: IFormProps, ref: React.Ref<any>) => {const {formOptions,formItemOptions,emitSubmit,formValue,} = props;const [form] = Form.useForm();// useImperativeHandle: 细化ref暴露的实例粒度useImperativeHandle(ref, (): IFormCompExportData=>({// 这里可以暴露SystemForm组件的所有内容 变量、方法、元素实例// 避免暴露出 完整的Form表单实例form 这里选择暴露获取字段value方法getFieldsValue的引用getFieldsValue: form.getFieldsValue}), [])const onFinish = (values: any) => {emitSubmit && emitSubmit(values);};return (<Formform={form}name={formOptions.name}labelCol={{ span: formOptions.labelCol }}wrapperCol={{ span: formOptions.wrapperCol }}initialValues={formValue}autoComplete={formOptions.autoComplete}size={formOptions.size}onFinish={onFinish}>{formItemOptions.map(item => {return (<Form.Itemkey={item.name}label={item.label}name={item.name}rules={item.rules}>{/*<CreateFormIpt formItem={item} />*/}{createFormIpt(item)}</Form.Item>);})}</Form>);
};// 因为有forwardRef包裹,所以SystemForm组件才可以使用第二个参数ref
export default forwardRef(SystemForm);
3、在BaseForm/createFormIpt.tsx中,抽取对不同类型的表单元素渲染
import { FormItemOptions } from '@/types/antd/form';
import React from 'react';
import { Button, Input, Select, Radio } from 'antd';const { TextArea} = Input;const createFormIpt = (formItem: FormItemOptions) => {if(formItem.name === 'password') {return (<Input type="password" prefix={formItem.prefix} placeholder={formItem.placeholder}/>)}const iptRenderMapByFormItemType: {[index: string]: React.JSX.Element} = {'input': <Input prefix={formItem.prefix} placeholder={formItem.placeholder} allowClear={formItem.allowClear}/>,'textarea':<TextArea rows={formItem.rows} placeholder={formItem.placeholder} allowClear={formItem.allowClear} />,'radio': <Radio.Group options={formItem.radioOptions?.options}/>,'select': <Selectplaceholder={formItem.placeholder}mode={formItem.selectOptions?.mode}allowClear={formItem.allowClear}options={formItem.selectOptions?.options}/>,'button': <>{formItem.formButtons?.map(itemBtn=>(<Buttonkey={itemBtn.key}type={itemBtn.buttonType}loading={itemBtn.btnLoadingStatus}block={itemBtn.block}htmlType={itemBtn.htmlType}>{itemBtn.btnDesc}</Button>))}</>,}return iptRenderMapByFormItemType[formItem.formItemType]
}export default createFormIpt;
4、在src/pages/PublishArticle/下,新建驱动表单的数据文件data.ts
import { FormOptions, FormItemOptions } from '@/types/antd/form';export const publishArticleFormValue = {'title': '11s','content': '','summary': '','categoryId': '','tags': [],'isComment': '0','isTop': '0','thumbnail': '',
}// 文章表单
export const publishArticleFormOptions: FormOptions = {name: 'publishArticle',autoComplete: 'off',size: 'large',labelCol: 4,wrapperCol: 20,
}export const publishArticleFormData: FormItemOptions[] = [{label: '文章标题',name: 'title',placeholder: '请输入文章标题',formItemType: 'input',allowClear: true,},{label: '文章摘要',name: 'summary',placeholder: '请输入文章摘要',formItemType: 'textarea',allowClear: true,},{label: '分类',name: 'categoryId',placeholder: '请选择',formItemType: 'select',selectOptions: {},allowClear: true,},{label: '标签',name: 'tags',placeholder: '请选择',formItemType: 'select',selectOptions: {mode: 'multiple'},allowClear: true,},{label: '允许评论',name: 'isComment',formItemType: 'radio',radioOptions: {options: [{ label: '正常', value: '1' },{ label: '停用', value: '0' }]}},{label: '是否置顶',name: 'isTop',formItemType: 'radio',radioOptions: {options: [{ label: '是', value: '1' },{ label: '否', value: '0' }]}},
]
5、在src/pages/PublishArticle/下,新建使用二次封装的Form组件的父组件index.ts
import React, { useRef, useState } from 'react';
import { PageContainer } from '@ant-design/pro-components';
import {publishArticleFormData,publishArticleFormOptions,publishArticleFormValue,
} from '@/pages/PublishArticle/data';
import { IFormCompExportData } from '@/types/antd/form';const PublishArticle: React.FC = () => {// useRef() 其 .current 属性被初始化为传入的参数(initialValue)// 所以useRef的初始化数据类型和useImperativeHandle返回的handle对象数据类型是一致的const publishArticleFormRef = useRef<IFormCompExportData>(null);const test = () => {const { getFieldsValue } = publishArticleFormRef.current as IFormCompExportData;// 获取表单的所有值getFieldsValue(true)console.log('表单收集的值', getFieldsValue(true));}return (<PageContainer><BaseFormformOptions={publishArticleFormOptions}formItemOptions={publishArticleFormData}formValue={publishArticleFormValue}ref={publishArticleFormRef}/><Button type="primary" onClick={test}>获取表单动态值</Button></PageContainer>);
};export default PublishArticle;
相关文章:
React hook+AntD pro实现Form表单的二次封装
React hookAntD pro实现Form表单的二次封装 封装Form表单1、在src/types下新建 antd/form/index.ts,进行Form表的配置、数据等类型的限制2、在 根目录/components 下新建 BaseForm/index.tsx文件3、在BaseForm/createFormIpt.tsx中,抽取对不同类型的表单…...
python异步切片下载文件(内置redis获取任务 mongo更新任务状态等)
异步切片下载二进制文件并上传桶删除本地文件 import json import os import asyncio from urllib import parseimport aiohttp import aioredis from motor.motor_asyncio import AsyncIOMotorClient from retrying import retry from minio import Minio from minio.error im…...
《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(10)-Fiddler如何设置捕获Firefox浏览器的Https会话
1.简介 经过上一篇对Fiddler的配置后,绝大多数的Https的会话,我们可以成功捕获抓取到,但是有些版本的Firefox浏览器仍然是捕获不到其的Https会话,需要我们更进一步的配置才能捕获到会话进行抓包。 2.宏哥环境 1.宏哥的环境是Wi…...
阿里云云原生弹性方案:用弹性解决集群资源利用率难题
作者:赫曦 随着上云的认知更加普遍,我们发现除了以往占大部分的互联网类型的客户,一些传统的企业,一些制造类的和工业型企业客户也都开始使用云原生的方式去做 IT 架构的转型,提高集群资源使用率也成为企业上云的一致…...
Spring-BeanPostProcessor PostConstruct init InitializingBean 执行顺序
执行顺序探究 新建一个对象用于测试 Component public class Student implements InitializingBean {private String name;private int age;public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}pu…...
【算法】递归
递归 递归初始递归:数列求和递归的应用:任意进制转换递归深度限制递归可视化:分形树递归可视化:谢尔宾斯基Sierpinski三角形递归的应用:汉诺塔递归的应用:探索迷宫 分治策略和递归优化问题兑换最少个数硬币…...
DC-1靶机刷题记录
靶机下载地址: 链接:https://pan.baidu.com/s/1GX7qOamdNx01622EYUBSow?pwd9nyo 提取码:9nyo 参考答案: https://c3ting.com/archives/kai-qi-vulnhnbshua-tiDC-1.pdf【【基础向】超详解vulnhub靶场DC-1】 https://www.bilibi…...
rust跟我学七:获取外网IP地址
图为RUST吉祥物 大家好,我是get_local_info作者带剑书生,这里用一篇文章讲解get_local_info是怎么获取到本机的外网IP地址。 首先,先要了解get_local_info是什么? get_local_info是一个获取linux系统信息的rust三方库,并提供一些常用功能,目前版本0.2.4。详细介绍地址:[…...
华为:交换机忘记console密码重置
一、背景 许多旧项目经过长时间使用后,因为没有特定的管理运维人员,初始对接人也将初始账号密码等重要信息丢失,现需要进后台查看配置或更改网络配置,需重置密码 二、重置密码,不重置设备方法 1、使用console插入交…...
2024年甘肃省职业院校技能大赛信息安全管理与评估 样题三 模块一
竞赛需要完成三个阶段的任务,分别完成三个模块,总分共计 1000分。三个模块内容和分值分别是: 1.第一阶段:模块一 网络平台搭建与设备安全防护(180 分钟,300 分)。 2.第二阶段:模块二…...
Go 中 slice 的 In 功能实现探索
文章目录 遍历二分查找map key性能总结 之前在知乎看到一个问题:为什么 Golang 没有像 Python 中 in 一样的功能?于是,搜了下这个问题,发现还是有不少人有这样的疑问。 补充:本文写于 2019 年。GO 现在已经支持泛型&am…...
pyDAL一个python的ORM(终) pyDAL的一些性能优化
一、大批量插入数据 对于 大量数据插入时,虽然pyDAL也手册中有个方法:bulk_insert(),但是手册也说了,虽然方法上是一次可以多条数据,如果后端数据库是关系型数据库,他转换为SQL时它是一条一条的插入的&…...
springboot log4j配置xml实例说明
提供样本配置代码 xml <?xml version"1.0" encoding"UTF-8"?> <!--日志级别以及优先级排序: OFF > FATAL > ERROR > WARN > INFO > DEBUG > TRACE > ALL --> <!-- status log4j2内部日志级别 --> <configurat…...
VsCode重新安装需要配机的ESLint和 Prettier - Code formatter 配置
新电脑安装完Vscode后,需要装几个插件,这里记录下: {"diffEditor.ignoreTrimWhitespace": false,"files.autoSave": "afterDelay","editor.codeActionsOnSave": {"source.fixAll.eslint"…...
录屏功能怎么打开?简单操作,一学就会!
录屏功能在当今互联网时代变得越来越重要,无论是游戏录制、在线课程录制还是屏幕操作演示,录屏功能都为我们提供了便捷的解决方案。可是您知道录屏功能怎么打开吗?接下来,让我们一起探索如何在电脑上开启录屏功能,记录…...
小程序显示兼容处理,home键处理
定义: env(safe-area-inset-bottom)和env(safe-area-inset-top)是CSS中的变量,用于获取设备底部和顶部安全区域的大小 示例: padding-bottom: calc(env(safe-area-inset-bottom) 12px); /* 兼容iOS> 11.2 */安全间距类型: …...
【java八股文】之JVM基础篇
【java八股文】之JVM基础篇-CSDN博客 【java八股文】之MYSQL基础篇-CSDN博客 【java八股文】之Redis基础篇-CSDN博客 【java八股文】之Spring系列篇-CSDN博客 【java八股文】之分布式系列篇-CSDN博客 【java八股文】之多线程篇-CSDN博客 【java八股文】之JVM基础篇-CSDN博…...
2024美赛数学建模思路 - 案例:异常检测
文章目录 赛题思路一、简介 -- 关于异常检测异常检测监督学习 二、异常检测算法2. 箱线图分析3. 基于距离/密度4. 基于划分思想 建模资料 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 一、简介 – 关于异常…...
【EI会议征稿通知】2024年通信技术与软件工程国际学术会议 (CTSE 2024)
2024年通信技术与软件工程国际学术会议 (CTSE 2024) 2024 International Conference on Communication Technology and Software Engineering (CTSE 2024) 2024年通信技术与软件工程国际学术会议 (CTSE 2024)将于2024年03月15-17日在中国长沙举行。会议专注于通信技术与软件工…...
Js面试之作用域与闭包
Js面试之作用域与闭包 作用域词法作用域动态作用域 闭包闭包使用场景封装私有变量模块化开发保持变量状态异步操作 注意事项 最近在整理一些前端面试中经常被问到的问题,分为vue相关、react相关、js相关、react相关等等专题,可持续关注后续内容ÿ…...
3步掌握Vidupe:基于内容识别的智能视频去重终极指南
3步掌握Vidupe:基于内容识别的智能视频去重终极指南 【免费下载链接】vidupe Vidupe is a program that can find duplicate and similar video files. V1.211 released on 2019-09-18, Windows exe here: 项目地址: https://gitcode.com/gh_mirrors/vi/vidupe …...
AI 智能体 8 层架构:生产级系统构建指南
AI 智能体(Agentic AI)革命的关键不在更好的提示词,而在于系统化的架构设计。随着企业竞相部署能够自主感知、推理、规划和行动的 AI 智能体(AI Agent),真正的挑战已经从"我们能构建吗?“转变为"…...
告别Modelsim命令行!用Notepad++插件NppExec一键检查Verilog语法(附详细配置命令)
硬件工程师的效率革命:Notepad与Verilog语法检查的终极整合方案 在数字电路设计领域,Verilog作为主流硬件描述语言,其语法检查是每位工程师日常工作中不可或缺的环节。传统工作流程中,工程师们不得不在文本编辑器与EDA工具之间频繁…...
研究生你的救星来了
为了找一个研究方向的核心文献,我要同时打开知网、Web of Science、IEEE Xplore三个数据库,翻几十篇顶刊摘要,还要手动整理每个文献的研究方法、核心结论,熬到凌晨两点,结果还是理不清整个领域的研究脉络。直到上个月朋…...
Camera Shakify:Blender相机抖动动画插件深度解析与性能优化指南
Camera Shakify:Blender相机抖动动画插件深度解析与性能优化指南 【免费下载链接】camera_shakify 项目地址: https://gitcode.com/gh_mirrors/ca/camera_shakify 在Blender动画制作中,相机运动的真实性直接影响观众的沉浸感。传统手动关键帧方法…...
终极音乐格式转换指南:3步完成音频解密与跨平台播放
终极音乐格式转换指南:3步完成音频解密与跨平台播放 【免费下载链接】unlock-music 在浏览器中解锁加密的音乐文件。原仓库: 1. https://github.com/unlock-music/unlock-music ;2. https://git.unlock-music.dev/um/web 项目地址: https:/…...
华硕笔记本性能优化神器:3步掌握G-Helper轻量级控制中心
华硕笔记本性能优化神器:3步掌握G-Helper轻量级控制中心 【免费下载链接】g-helper Lightweight Armoury Crate alternative for Asus laptops with nearly the same functionality. Works with ROG Zephyrus, Flow, TUF, Strix, Scar, ProArt, Vivobook, Zenbook, …...
5分钟掌握FanControl:Windows风扇控制终极指南,告别噪音与过热烦恼
5分钟掌握FanControl:Windows风扇控制终极指南,告别噪音与过热烦恼 【免费下载链接】FanControl.Releases This is the release repository for Fan Control, a highly customizable fan controlling software for Windows. 项目地址: https://gitcode…...
DMA链表模式(LLI)实战:如何用一块内存搞定不连续地址的数据搬运?
DMA链表模式(LLI)实战:如何用一块内存搞定不连续地址的数据搬运? 在物联网和通信系统的开发中,我们经常遇到需要从多个分散的数据源收集信息,或将数据分发到不同目标地址的场景。比如一个智能家居网关需要同时处理来自温湿度传感…...
openLCA 2.6.2 完整安装与使用指南:免费开源的生命周期评估解决方案
openLCA 2.6.2 完整安装与使用指南:免费开源的生命周期评估解决方案 【免费下载链接】olca-app Source code of openLCA 项目地址: https://gitcode.com/gh_mirrors/ol/olca-app openLCA 是一款功能强大的开源生命周期评估软件,专门用于产品从原材…...
