react+antd封装一个可回车自定义option的select并且与某些内容相互禁用

需求背景

一个select框 现在要求可多选 并且原有一个any的选项 其他选项为输入后回车自己增加 若选择了any 则其他选项不可选择反之选择其他选项any不可选择 并且回车新增时也不可直接加入到选中数组只加入到option内 并且不可重复添加新内容

实现过程

javascript 复制代码
 <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('');
    }
  };
相关推荐
林强1812 小时前
前端文件预览docx、pptx和xlsx
前端
像是套了虚弱散4 小时前
DevEco Studio与Web联合开发:打造鸿蒙混合应用的全景指南
开发语言·前端·华为·harmonyos·鸿蒙
衬衫chenshan5 小时前
【CTF】强网杯2025 Web题目writeup
前端
飞翔的佩奇5 小时前
【完整源码+数据集+部署教程】【天线&水】舰船战舰检测与分类图像分割系统源码&数据集全套:改进yolo11-repvit
前端·python·yolo·计算机视觉·数据集·yolo11·舰船战舰检测与分类图像分割系统
哆啦A梦15886 小时前
点击Top切换数据
前端·javascript·vue.js
程序猿追6 小时前
Vue组件化开发
前端·html
艾德金的溪7 小时前
redis-7.4.6部署安装
前端·数据库·redis·缓存
小光学长7 小时前
基于Vue的2025年哈尔滨亚冬会志愿者管理系统5zqg6m36(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。
前端·数据库·vue.js
@PHARAOH7 小时前
WHAT - 受控组件和非受控组件
前端·javascript·react.js
生莫甲鲁浪戴7 小时前
Android Studio新手开发第二十六天
android·前端·android studio