需求背景
一个select框 现在要求可多选 并且原有一个any的选项 其他选项为输入后回车自己增加 若选择了any 则其他选项不可选择反之选择其他选项any不可选择 并且回车新增时也不可直接加入到选中数组只加入到option内 并且不可重复添加新内容
实现过程
<Form.Item label={formatMessage({ id: 'label.alarm.SourceAddress' })}
name="sourceAddress">
<Select
mode="multiple"
maxTagCount={3}
showSearch
searchValue={inputValue}
onChange={(e) => createSelectionHandler(e, 'any', sourceList, setSourceList)}
placeholder={formatMessage({ id: 'select.placeholder' })}
onSearch={setInputValue}
onInputKeyDown={sourceHandleKeyDown}
options={sourceList}
getPopupContainer={(triggerNode) => triggerNode.parentElement ||
document.body}
/>
</Form.Item>
//js部分
// 源地址列表
const [sourceList, setSourceList] = useState([{ value: 'any', label: 'any', disabled:
false }]);
// 源地址输入框
const [inputValue, setInputValue] = useState('');
// 通用处理函数
const createSelectionHandler = (specialValue, key, stateList, setState) => {
const newList = stateList.map((item) => ({
...item,
disabled: specialValue.includes(key)
? item.value !== key // 如果选中特殊值,禁用其他选项
: specialValue.length > 0 // 如果选中普通值,禁用特殊值
? item.value === key
: false, // 没有选中时恢复默认
}));
setState(newList);
};
// 源地址处理键盘事件(回车)
const sourceHandleKeyDown = (e) => {
if (e.key === 'Enter' && inputValue.trim()) {
const newValue = inputValue.trim();
const lis = addAlarmForm.getFieldValue('sourceAddress');
if (!lis.includes(newValue)) {
if (lis.includes('any')) {
setSourceList([
...sourceList,
{
value: newValue,
label: newValue,
disabled: true,
},
]);
} else {
setSourceList(
[
...sourceList,
{
value: newValue,
label: newValue,
disabled: false,
},
].map((item) => ({
...item,
disabled: item.value == 'any',
})),
);
addAlarmForm.setFieldsValue({
sourceAddress: [...lis, newValue],
});
}
}
setInputValue('');
}
};