2021SC@SDUSC
AutoComplete自动完成
用法:
• 需要一个输入框而不是选择器。
• 需要输入建议/辅助提示。
和 Select 的区别是:
• AutoComplete 是一个带提示的文本输入框,用户可以自由输入,关键词是辅助输入。
Select 是在限定的可选项中进行选择,关键词是选择。
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 | 下拉菜单和选择器同宽。默认将设置 | boolean | number | true | |
filterOption | 是否根据输入项进行筛选。当其为一个函数时,会接收 | 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) | - |
注意
AutoComplete 组件是一个支持自动提示的 Input 组件,因而其不具有 labelInValue
等影响 value 展示的属性。在 v3 版本,AutoComplete 实现存在输入值如果遇到 value
与 label
相同时无法映射的问题。 v4 中不再支持 label
为值的输入形态。
此外为了统一 API,dataSource
改为 options
:
v3
dataSource = ['light', 'bamboo'];
// or
dataSource = [
{ value: 'light', text: 'Light' },
{ value: 'bamboo', text: 'Bamboo' },
];
v4
options = [
{ value: 'light', label: 'Light' },
{ value: 'bamboo', label: 'Bamboo' },
];
部分源码
export interface AutoCompleteProps
extends Omit<
InternalSelectProps<string>,
'inputIcon' | 'loading' | 'mode' | 'optionLabelProp' | 'labelInValue'
> {
dataSource?: DataSourceItemType[];
}
Omit<K,T>用于从另一个对象类型中剔除某些属性,并创建一个新的对象类型:
K:是对象类型名称,T:是剔除K类型中的属性名称
function isSelectOptionOrSelectOptGroup(child: any): Boolean {
return child && child.type && (child.type.isSelectOption || child.type.isSelectOptGroup);
}
用于检测是select还是optgroup
标签把相关的选项组合在一起. 当使用一个长的选项列表时,对相关的选项进行组合会使处理更加容易。
const AutoComplete: React.ForwardRefRenderFunction<RefSelectProps, AutoCompleteProps> = (
props,
ref,
) => {
const { prefixCls: customizePrefixCls, className, children, dataSource } = props;
const childNodes: React.ReactElement[] = toArray(children);
React.forwardRef 会创建一个React组件,这个组件能够将其接受的 ref 属性转发到其组件树下的另一个组件中。
prop 着重于数据的传递,它并不能调用子组件里的属性和方法。像创建文章组件时,自定义标题和内容这样的使用场景,最适合使用prop。
ref 着重于索引,主要用来调用子组件里的属性和方法,其实并不擅长数据传递。而且ref用在dom元素的时候,能使到选择器的作用,这个功能比作为索引更常有用到。
// ============================= Input =============================
let customizeInput: React.ReactElement | undefined;
if (
childNodes.length === 1 &&
isValidElement(childNodes[0]) &&
!isSelectOptionOrSelectOptGroup(childNodes[0])
) {
[customizeInput] = childNodes;
}
const getInputElement = customizeInput ? (): React.ReactElement => customizeInput! : undefined;
判断只有一个子节点且为react组件,且其不是selectoption或optgroup
customizeInput赋值为子节点
// ============================ Warning ============================
React.useEffect(() => {
devWarning(
!('dataSource' in props),
'AutoComplete',
'`dataSource` is deprecated, please use `options` instead.',
);
devWarning(
!customizeInput || !('size' in props),
'AutoComplete',
'You need to control style self instead of setting `size` when using customize input.',
);
}, []);
警告
应使用options替代dataSource
不应使用size属性控制