前言
表单可以说是前端最常见的一种组件,特别是在进行搜索的时候使用的最频繁,自定义表单组件,丰富了搜索框的类型,使数据展现的更灵活
内容讲解
1、官方介绍
AntD-Formhttps://ant.design/components/form-cn#form-demo-customized-form-controls
2、使用讲解
父组件
父组件非常简单,就是使用<Form.Item>包裹着自定义的组件就可以了
<Form.Item name="dataIds" className="tag-input-box">
<TagList
showName="序号"
/>
</Form.Item>
子组件
子组件也就是自定义组件,相对父组件而言有两点需要注意
1、接受两个参数value和onChange
2、value为父组件传递的值,onChange将新值传递给父组件
const {
value,
onChange
} = props;
// 接收
const [tagList, setTagList] = useState<any>(value || []);
//传递
onChange(tagList);
案例
import React, { FC, useCallback, useRef, useState, useEffect } from 'react';
import { Input, Tag } from 'antd';
interface AttrType {
id: string;
type: string;
label?: string;
name?: string;
value?: string;
}
interface TagListPropsType {
value?: Array<AttrType>;
onChange?: (params: Array<AttrType>) => void;
}
const TagList: FC<TagListPropsType> = (props) => {
const {
value, // 父组件传递过来的数据
onChange, // 父组件传递过来的回调函数
} = props;
const [tagList, setTagList] = useState<any>(value || []); // 存储tag数据
const inputRef = useRef<any>(null); // 存储输入框的ref
const [inputValue, setInputValue] = useState<string>(''); // 存储输入框的值
const handlePressEnter = useCallback(
(e) => {
// 新增数据,回车或失焦
const val = e.target.value;
if (!val || val.length <= 0) {
return; // 如果输入框中无内容,则不添加
}
const list = [...tagList];
if (inputRef.current) {
setInputValue(''); // 清空输入框的值
}
if (list.some((item: any) => item.value === val)) {
// 如果已经存在,则不添加(去重);
return;
}
list.push({
text: val,
value: val
});
setTagList(list);
if (onChange) {
onChange(list); // 通知父组件数据发生了变化
}
e.preventDefault(); // 阻止事件冒泡
},
[tagList, onChange, inputRef]
);
const handleClose = useCallback(
(valueItem) => {
const list = [...tagList];
const newList = list.filter(
(subItem: any) => subItem.value !== valueItem
);
setTagList(newList);
if (onChange) {
onChange(newList);
}
},
[tagList, setTagList, onChange]
);
const handleKeyDown = useCallback(
(e) => {
// 检测是否按下了删除键(Backspace)或删除键(Delete),且当前输入框中无内容
if (
(e.keyCode === 8 || e.keyCode === 46) &&
inputRef.current?.input.value === ''
) {
const list = [...tagList];
list.pop();
setTagList([...list]);
if (onChange) {
onChange(list); // 通知父组件数据发生了变化
}
}
},
[tagList, setTagList, onChange]
);
useEffect(() => {
if (value) {
setTagList(value); // 初始化数据
}
}, [value]);
return (
<div>
{tagList.length > 0 && (
<div>
{tagList.map((item: any) => (
<Tag
key={item.value}
closable
onClose={() => handleClose(item.value)}
className="tag"
>
{item.text}
</Tag>
))}
</div>
)}
<Input
placeholder="请输入内容,按enter键隔开"
onPressEnter={handlePressEnter}
variant="borderless"
onBlur={(e) => {
handlePressEnter(e);
}}
ref={inputRef}
onChange={(e: any) => { setInputValue(e.target.value); }}
onKeyDown={handleKeyDown}
value={inputValue}
/>
</div>
);
};
export default TagList;