AutoComplete自动完成

输入框自动完成功能。

何时使用#

需要自动完成时。

代码演示



基本使用,通过 options 设置自动完成的数据源。

expand codeexpand code
import React, { useState } from 'react';
import { AutoComplete } from 'antd';

const mockVal = (str: string, repeat: number = 1) => {
  return {
    value: str.repeat(repeat),
  };
};
const Complete: React.FC = () => {
  const [value, setValue] = useState('');
  const [options, setOptions] = useState<{ value: string }[]>([]);
  const onSearch = (searchText: string) => {
    setOptions(
      !searchText ? [] : [mockVal(searchText), mockVal(searchText, 2), mockVal(searchText, 3)],
    );
  };
  const onSelect = (data: string) => {
    console.log('onSelect', data);
  };
  const onChange = (data: string) => {
    setValue(data);
  };
  return (
    <>
      <AutoComplete
        options={options}
        style={{ width: 200 }}
        onSelect={onSelect}
        onSearch={onSearch}
        placeholder="input here"
      />
      <br />
      <br />
      <AutoComplete
        value={value}
        options={options}
        style={{ width: 200 }}
        onSelect={onSelect}
        onSearch={onSearch}
        onChange={onChange}
        placeholder="control mode"
      />
    </>
  );
};

ReactDOM.render(<Complete />, mountNode);

自定义输入组件。

expand codeexpand code
import React, { useState } from 'react';
import { AutoComplete, Input } from 'antd';

const { TextArea } = Input;

const Complete: React.FC = () => {
  const [options, setOptions] = useState<{ value: string }[]>([]);
  const handleSearch = (value: string) => {
    setOptions(
      !value ? [] : [{ value }, { value: value + value }, { value: value + value + value }],
    );
  };

  const handleKeyPress = (ev: React.KeyboardEvent<HTMLTextAreaElement>) => {
    console.log('handleKeyPress', ev);
  };

  const onSelect = (value: string) => {
    console.log('onSelect', value);
  };

  return (
    <AutoComplete
      options={options}
      style={{ width: 200 }}
      onSelect={onSelect}
      onSearch={handleSearch}
    >
      <TextArea
        placeholder="input here"
        className="custom"
        style={{ height: 50 }}
        onKeyPress={handleKeyPress}
      />
    </AutoComplete>
  );
};

ReactDOM.render(<Complete />, mountNode);
expand codeexpand code
import { Input, AutoComplete } from 'antd';
import { UserOutlined } from '@ant-design/icons';

const renderTitle = (title: string) => {
  return (
    <span>
      {title}
      <a
        style={{ float: 'right' }}
        href="https://www.google.com/search?q=antd"
        target="_blank"
        rel="noopener noreferrer"
      >
        more
      </a>
    </span>
  );
};

const renderItem = (title: string, count: number) => {
  return {
    value: title,
    label: (
      <div
        style={{
          display: 'flex',
          justifyContent: 'space-between',
        }}
      >
        {title}
        <span>
          <UserOutlined /> {count}
        </span>
      </div>
    ),
  };
};

const options = [
  {
    label: renderTitle('Libraries'),
    options: [renderItem('AntDesign', 10000), renderItem('AntDesign UI', 10600)],
  },
  {
    label: renderTitle('Solutions'),
    options: [renderItem('AntDesign UI FAQ', 60100), renderItem('AntDesign FAQ', 30010)],
  },
  {
    label: renderTitle('Articles'),
    options: [renderItem('AntDesign design language', 100000)],
  },
];

const Complete: React.FC = () => (
  <AutoComplete
    dropdownClassName="certain-category-search-dropdown"
    dropdownMatchSelectWidth={500}
    style={{ width: 250 }}
    options={options}
  >
    <Input.Search size="large" placeholder="input here" />
  </AutoComplete>
);

ReactDOM.render(<Complete />, mountNode);
.certain-category-search-dropdown .ant-select-dropdown-menu-item-group-title {
  color: #666;
  font-weight: bold;
}

.certain-category-search-dropdown .ant-select-dropdown-menu-item-group {
  border-bottom: 1px solid #f6f6f6;
}

.certain-category-search-dropdown .ant-select-dropdown-menu-item {
  padding-left: 16px;
}

.certain-category-search-dropdown .ant-select-dropdown-menu-item.show-all {
  text-align: center;
  cursor: default;
}

.certain-category-search-dropdown .ant-select-dropdown-menu {
  max-height: 300px;
}

也可以直接传 AutoComplete.Option 作为 AutoCompletechildren,而非使用 options

expand codeexpand code
import React, { useState } from 'react';
import { AutoComplete } from 'antd';

const { Option } = AutoComplete;

const Complete: React.FC = () => {
  const [result, setResult] = useState<string[]>([]);
  const handleSearch = (value: string) => {
    let res: string[] = [];
    if (!value || value.indexOf('@') >= 0) {
      res = [];
    } else {
      res = ['gmail.com', '163.com', 'qq.com'].map(domain => `${value}@${domain}`);
    }
    setResult(res);
  };
  return (
    <AutoComplete style={{ width: 200 }} onSearch={handleSearch} placeholder="input here">
      {result.map((email: string) => (
        <Option key={email} value={email}>
          {email}
        </Option>
      ))}
    </AutoComplete>
  );
};

ReactDOM.render(<Complete />, mountNode);

不区分大小写的 AutoComplete

expand codeexpand code
import { AutoComplete } from 'antd';

const options = [
  { value: 'Burns Bay Road' },
  { value: 'Downing Street' },
  { value: 'Wall Street' },
];

const Complete: React.FC = () => (
  <AutoComplete
    style={{ width: 200 }}
    options={options}
    placeholder="try to type `b`"
    filterOption={(inputValue, option) =>
      option.value.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1
    }
  />
);

ReactDOM.render(<Complete />, mountNode);
expand codeexpand code
import React, { useState } from 'react';
import { Input, AutoComplete } from 'antd';
import { SelectProps } from 'antd/es/select';

function getRandomInt(max: number, min: number = 0) {
  return Math.floor(Math.random() * (max - min + 1)) + min; // eslint-disable-line no-mixed-operators
}

const searchResult = (query: string) => {
  return new Array(getRandomInt(5))
    .join('.')
    .split('.')
    .map((item, idx) => {
      const category = `${query}${idx}`;
      return {
        value: category,
        label: (
          <div
            style={{
              display: 'flex',
              justifyContent: 'space-between',
            }}
          >
            <span>
              Found {query} on{' '}
              <a
                href={`https://s.taobao.com/search?q=${query}`}
                target="_blank"
                rel="noopener noreferrer"
              >
                {category}
              </a>
            </span>
            <span>{getRandomInt(200, 100)} results</span>
          </div>
        ),
      };
    });
};

const Complete: React.FC = () => {
  const [options, setOptions] = useState<SelectProps<object>['options']>([]);

  const handleSearch = (value: string) => {
    setOptions(value ? searchResult(value) : []);
  };

  const onSelect = (value: string) => {
    console.log('onSelect', value);
  };

  return (
    <AutoComplete
      dropdownMatchSelectWidth={252}
      style={{ width: 300 }}
      options={options}
      onSelect={onSelect}
      onSearch={handleSearch}
    >
      <Input.Search size="large" placeholder="input here" enterButton />
    </AutoComplete>
  );
};

ReactDOM.render(<Complete />, mountNode);

API#

参数说明类型默认值版本
allowClear支持清除, 单选模式有效booleanfalse
autoFocus自动获取焦点booleanfalse
backfill使用键盘选择选项的时候把选中项回填到输入框中booleanfalse
children (自定义输入框)自定义输入框HTMLInputElement | HTMLTextAreaElement | React.ReactElement<InputProps><Input />
children (自动完成的数据源)自动完成的数据源React.ReactElement<OptionProps> | Array<React.ReactElement<OptionProps>>-
defaultActiveFirstOption是否默认高亮第一个选项booleantrue
defaultValue指定默认选中的条目string-
disabled是否禁用booleanfalse
dropdownClassName下拉菜单的 className 属性string-
dropdownMatchSelectWidth下拉菜单和选择器同宽。默认将设置 min-width,当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动boolean | numbertrue
filterOption是否根据输入项进行筛选。当其为一个函数时,会接收 inputValue option 两个参数,当 option 符合筛选条件时,应返回 true,反之则返回 falseboolean | function(inputValue, option)true
getPopupContainer菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。示例function(triggerNode)() => document.body
placeholder输入框提示string-
value指定当前选中的条目string-
onBlur失去焦点时的回调function()-
onChange选中 option,或 input 的 value 变化时,调用此函数function(value)-
onFocus获得焦点时的回调function()-
onSearch搜索补全项的时候调用function(value)-
onSelect被选中时调用,参数为选中项的 value 值function(value, option)-
defaultOpen是否默认展开下拉菜单boolean-
open是否展开下拉菜单boolean-
options数据化配置选项内容,相比 jsx 定义会获得更好的渲染性能{ label, value }[]-
onDropdownVisibleChange展开下拉菜单的回调function(open)-
notFoundContent当下拉列表为空时显示的内容ReactNode-

方法#

名称描述版本
blur()移除焦点
focus()获取焦点

FAQ#

为何受控状态下使用 onSearch 无法输入中文?#

请使用 onChange 进行受控管理。onSearch 触发于搜索输入,与 onChange 时机不同。此外,点选选项时也不会触发 onSearch 事件。

相关 issue:#18230 #17916

v3 的部分属性为何在 v4 中没有了?#

AutoComplete 组件是一个支持自动提示的 Input 组件,因而其不具有 labelInValue 等影响 value 展示的属性。在 v3 版本,AutoComplete 实现存在输入值如果遇到 valuelabel 相同时无法映射的问题。 v4 中不再支持 label 为值的输入形态。

Steps步骤条Cascader级联选择