AutoComplete自动完成
输入框自动完成功能。
何时使用
需要一个输入框而不是选择器。
需要输入建议/辅助提示。
和 Select 的区别是:
AutoComplete 是一个带提示的文本输入框,用户可以自由输入,关键词是辅助输入。
Select 是在限定的可选项中进行选择,关键词是选择。
代码演示

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

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 (<><AutoCompleteoptions={options}style={{ width: 200 }}onSelect={onSelect}onSearch={onSearch}placeholder="input here"/><br /><br /><AutoCompletevalue={value}options={options}style={{ width: 200 }}onSelect={onSelect}onSearch={onSearch}onChange={onChange}placeholder="control mode"/></>);};ReactDOM.render(<Complete />, mountNode);

自定义输入组件。
TypeScript
JavaScript

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 (<AutoCompleteoptions={options}style={{ width: 200 }}onSelect={onSelect}onSearch={handleSearch}><TextAreaplaceholder="input here"className="custom"style={{ height: 50 }}onKeyPress={handleKeyPress}/></AutoComplete>);};ReactDOM.render(<Complete />, mountNode);

查询模式: 确定类目 示例。
TypeScript
JavaScript

import { Input, AutoComplete } from 'antd';import { UserOutlined } from '@ant-design/icons';const renderTitle = (title: string) => {return (<span>{title}<astyle={{ 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: (<divstyle={{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 = () => (<AutoCompletedropdownClassName="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 作为 AutoComplete 的 children,而非使用 options。
TypeScript
JavaScript

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
TypeScript
JavaScript

import { AutoComplete } from 'antd';const options = [{ value: 'Burns Bay Road' },{ value: 'Downing Street' },{ value: 'Wall Street' },];const Complete: React.FC = () => (<AutoCompletestyle={{ width: 200 }}options={options}placeholder="try to type `b`"filterOption={(inputValue, option) =>option.value.toUpperCase().indexOf(inputValue.toUpperCase()) !== -1}/>);ReactDOM.render(<Complete />, mountNode);

查询模式: 不确定类目 示例。
TypeScript
JavaScript

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: (<divstyle={{display: 'flex',justifyContent: 'space-between',}}><span>Found {query} on{' '}<ahref={`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 (<AutoCompletedropdownMatchSelectWidth={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 | 支持清除 | boolean | false | |
| autoFocus | 自动获取焦点 | boolean | false | |
| backfill | 使用键盘选择选项的时候把选中项回填到输入框中 | boolean | false | |
| children (自动完成的数据源) | 自动完成的数据源 | React.ReactElement<OptionProps> | Array<React.ReactElement<OptionProps>> | - | |
| children (自定义输入框) | 自定义输入框 | HTMLInputElement | HTMLTextAreaElement | React.ReactElement<InputProps> | <Input /> | |
| defaultActiveFirstOption | 是否默认高亮第一个选项 | boolean | true | |
| defaultOpen | 是否默认展开下拉菜单 | boolean | - | |
| defaultValue | 指定默认选中的条目 | string | - | |
| disabled | 是否禁用 | boolean | false | |
| dropdownClassName | 下拉菜单的 className 属性 | string | - | |
| dropdownMatchSelectWidth | 下拉菜单和选择器同宽。默认将设置 min-width,当值小于选择框宽度时会被忽略。false 时会关闭虚拟滚动 | boolean | number | true | |
| filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 inputValue option 两个参数,当 option 符合筛选条件时,应返回 true,反之则返回 false | boolean | function(inputValue, option) | true | |
| getPopupContainer | 菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。示例 | function(triggerNode) | () => document.body | |
| notFoundContent | 当下拉列表为空时显示的内容 | ReactNode | - | |
| open | 是否展开下拉菜单 | boolean | - | |
| options | 数据化配置选项内容,相比 jsx 定义会获得更好的渲染性能 | { label, value }[] | - | |
| placeholder | 输入框提示 | string | - | |
| value | 指定当前选中的条目 | string | - | |
| onBlur | 失去焦点时的回调 | function() | - | |
| onChange | 选中 option,或 input 的 value 变化时,调用此函数 | function(value) | - | |
| onDropdownVisibleChange | 展开下拉菜单的回调 | function(open) | - | |
| onFocus | 获得焦点时的回调 | function() | - | |
| onSearch | 搜索补全项的时候调用 | function(value) | - | |
| onSelect | 被选中时调用,参数为选中项的 value 值 | function(value, option) | - |
方法
| 名称 | 描述 | 版本 |
|---|---|---|
| blur() | 移除焦点 | |
| focus() | 获取焦点 |
FAQ
为何受控状态下使用 onSearch 无法输入中文?
请使用 onChange 进行受控管理。onSearch 触发于搜索输入,与 onChange 时机不同。此外,点选选项时也不会触发 onSearch 事件。
v3 的部分属性为何在 v4 中没有了?
AutoComplete 组件是一个支持自动提示的 Input 组件,因而其不具有 labelInValue 等影响 value 展示的属性。在 v3 版本,AutoComplete 实现存在输入值如果遇到 value 与 label 相同时无法映射的问题。 v4 中不再支持 label 为值的输入形态。
此外为了统一 API,dataSource 改为 options 你可以如下转换:
v3
dataSource = ['light', 'bamboo'];// ordataSource = [{ value: 'light', text: 'Light' },{ value: 'bamboo', text: 'Bamboo' },];
v4
options = [{ value: 'light', label: 'Light' },{ value: 'bamboo', label: 'Bamboo' },];