Skip to main content

Select 选择器

下拉选择器。

引入​

import {Select} from 'acud';

基本用法​

function App() {
const {Option} = Select;
const [value, setValue] = useState('data1');

const handleChange = val => {
console.log(val);
setValue(val);
};

return (
<div className="acux-demo-column">
<h5>无默认值</h5>
<Select>
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>

<h5>有默认值(非受控)</h5>
<Select defaultValue={value}>
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>

<h5>有固定值(受控)</h5>
<Select value={value}>
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>

<h5>通用方法</h5>
<Select value={value} onChange={handleChange}>
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>
</div>
);
}

禁用状态​

<Select disabled>
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>

传入列表的用法​

function App() {
const {Option} = Select;

const optionsDemo = [
{value: 'data1', label: 'data1'},
{value: 'data2', label: 'data2'},
{value: 'data3', label: 'data3'},
{value: 'data4', label: 'data4'}
];

return (
<div className="acux-demo-column">
<Select options={optionsDemo} />
<Select>
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>
</div>
);
}

空选项​

<div className="acux-demo-column">
<Select options={[]} />
<Select></Select>
</div>

可清空​

<Select allowClear>
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>

弹窗位置​

<div className="acux-demo-column">
<h5>bottomLeft</h5>
<Select placement="bottomLeft">
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>

<h5>bottomRight</h5>
<Select placement="bottomRight">
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>

<h5>topLeft</h5>
<Select placement="topLeft">
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>

<h5>topRight</h5>
<Select placement="topRight">
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>
</div>

弹窗滚动逻辑​

弹层展示逻辑,默认为可视区域滚动,可配置成滚动区域滚动。

<div className="acux-demo-column">
<h5>viewport</h5>
<Select popupOverflow="viewport">
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>

<h5>scroll</h5>
<Select popupOverflow="scroll">
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3">data3</Option>
<Option value="data4">data4</Option>
</Select>
</div>

下拉多选​

多选,从已有条目中选择。

function App() {
const {Option} = Select;

const optionsDemo = [
{value: 'data1', label: 'data1'},
{value: 'data2', label: 'data2'},
{value: 'data3', label: 'data3', disabled: true},
{value: 'data4', label: 'data4'}
];

return (
<div className="acux-demo-column">
<Select mode="multiple" options={optionsDemo} />
<Select mode="multiple" defaultValue={['data1', 'data2']} options={optionsDemo} />
<Select mode="multiple">
<Option value="data1">data1</Option>
<Option value="data2">data2</Option>
<Option value="data3" disabled>data3</Option>
<Option value="data4">data4</Option>
</Select>
</div>
);
}

带搜索框​

function App() {
const {Option} = Select;

function onChange(value) {
console.log(`selected ${value}`);
}

function onBlur() {
console.log('blur');
}

function onFocus() {
console.log('focus');
}

function onSearch(val) {
console.log('search:', val);
}

return (
<Select
showSearch
style={{width: 200}}
optionFilterProp="children"
onChange={onChange}
onFocus={onFocus}
onBlur={onBlur}
onSearch={onSearch}
filterOption={(input, option) =>
option.children.toLowerCase().indexOf(input.toLowerCase()) >= 0
}
>
<Option value="jack">Jack</Option>
<Option value="lucy">Lucy</Option>
<Option value="tom">Tom</Option>
</Select>
);
}

多选搜索​

function App() {
const {Option} = Select;

const children = [];
for (let i = 10; i < 16; i++) {
children.push(
<Option value={i.toString(36) + i}>{i.toString(36) + i}</Option>
);
}

const children2 = [
<Option value="data1">data1</Option>,
<Option value="data2">data2</Option>,
<Option value="data3">data3</Option>,
<Option value="data4" disabled>
data4
</Option>,
<Option value="data5">data5</Option>,
<Option value="data6">data6</Option>,
<Option value="data7">data7</Option>,
<Option value="sakta8">SaKta8</Option>,
<Option value="data9">data9</Option>,
<Option value="data10" disabled>
data10
</Option>,
<Option value="data11">data11</Option>
];

function handleChange(value) {
console.log(`selected ${value}`);
}

return (
<div className="acux-demo-column">
<Select
mode="multiple"
allowClear
showSearch
style={{width: '100%'}}
defaultValue={['a10', 'c12']}
onChange={handleChange}
>
{children}
</Select>
<Select
mode="multiple"
style={{width: '100%'}}
allowClear
showSearch
placeholder="请选择"
defaultValue={['data3', 'data4']}
onChange={handleChange}
>
{children2}
</Select>
</div>
);
}

大数据量、展示 title​

function App() {
const {Option} = Select;

function handleChange(value) {
console.log(`selected ${value}`);
}

function getOptions() {
const options = [];
for (let i = 3, len = 100000; i < len; i++) {
options.push(
<Option key={i} title={`data${i}`} value={`data${i}`}>
data{i}
</Option>
);
}
return options;
}

const children = [
<Option value="data1">data10000000000000000000</Option>,
<Option value="data2">data2000000000000000</Option>,
<Option value="data3">data300000000000000000</Option>,
<Option value="data4">data400000000000000000</Option>,
<Option value="data5">data50000000000000000</Option>,
<Option value="data6">data60000000000000000</Option>,
<Option value="data7">data70000000000000000</Option>,
<Option value="data8">data80000000000000000</Option>,
<Option value="data9">data90000000000000000</Option>,
<Option value="data10">data100000000000000000</Option>,
<Option value="data11">data11000000000000000</Option>
];

return (
<div className="acux-demo-column">
<Select
defaultValue="data2"
showTitle
maxTagTextLength={8}
style={{width: 160}}
onChange={handleChange}
>
<Option key={1} value="data1">
data1
</Option>
<Option key={2} value="data2">
我的数据量非常大,已经超过了最大宽度了
</Option>
{getOptions()}
</Select>
<Select
mode="multiple"
style={{width: 160}}
showTitle
onChange={handleChange}
>
{children}
</Select>
</div>
);
}

自定义 option 渲染​

option children 外层加 Tooltip 并正确显示的例子 此方法可以不干扰搜索高亮效果。

function App() {
const {Option} = Select;

const children = [
<Option value="data1">data177777756764564654564546564546564</Option>,
<Option value="data2">data2</Option>,
<Option value="data3">data3</Option>,
<Option value="data4">data4</Option>,
<Option value="data5">data5</Option>,
<Option value="data6">data6</Option>,
<Option value="data7">data7</Option>,
<Option value="data8">data8</Option>,
<Option value="data9">data9</Option>,
<Option value="data10">data10</Option>,
<Option value="data11">data11</Option>
];

const options = [
{value: 'data1', label: 'data11111111111111111111111111111'},
{value: 'data2', label: 'data2'},
{value: 'data3', label: 'data3'},
{value: 'data4', label: 'data4'},
{value: 'data5', label: 'data5'}
];

function handleChange(value) {
console.log(`selected ${value}`);
}

return (
<div className="acux-demo-column">
<Select
mode="multiple"
maxTagCount={6}
allowClear
style={{width: 200}}
maxTagTextLength={10}
placeholder="请选择"
defaultValue={['data3', 'data4']}
onChange={handleChange}
optionRender={(label, option) => {
return (
<Tooltip placement="right" title={label}>
<span style={{
display: 'inline-block',
maxWidth: '100%',
overflow: 'hidden',
textOverflow: 'ellipsis',
verticalAlign: 'middle'
}}
>{label}
</span>
</Tooltip>
);
}}
>
{children}
</Select>
<Select
mode="multiple"
maxTagCount={6}
allowClear
style={{width: 200}}
maxTagTextLength={10}
placeholder="请选择"
onChange={handleChange}
options={options}
optionRender={(label, option) => {
return (
<Tooltip placement="right" title={label}>
<span style={{
display: 'inline-block',
maxWidth: '100%',
overflow: 'hidden',
textOverflow: 'ellipsis',
verticalAlign: 'middle'
}}
>{label}
</span>
</Tooltip>
);
}}
/>
</div>
);
}

下拉分组​

用 OptGroup 进行选项分组。

function App() {
const {Option, OptGroup} = Select;

function handleChange(value) {
console.log(`selected ${value}`);
}

function handleExpandChange(key) {
console.log('expand key:', key);
}

return (
<div className="acux-demo-column">
<Select
defaultValue="zhangsan"
keepExpand
style={{width: 320}}
groupSelectorRender={(groupLabel, value) => value}
onChange={handleChange}
>
<OptGroup label="Manager" key="manager">
<Option value="zhangsan">zhangsan</Option>
<Option value="lisi">lisi</Option>
</OptGroup>
<OptGroup label="Engineer">
<Option value="xiaoming">xiaoming</Option>
</OptGroup>
<Option value="xiaodong">xiaodong</Option>
</Select>

<Select
defaultValue="zhangsan"
defaultExpandGroupKey={['manager']}
style={{width: 320}}
onChange={handleChange}
onExpandChange={handleExpandChange}
>
<OptGroup label="Manager" key="manager">
<Option value="zhangsan">zhangsan</Option>
<Option value="lisi">lisi</Option>
</OptGroup>
<OptGroup label="Engineer">
<Option value="xiaoming">xiaoming</Option>
</OptGroup>
<Option value="xiaodong">xiaodong</Option>
</Select>

<Select
defaultValue="zhangsan"
style={{width: 320}}
defaultExpandGroupKey={['manager']}
mode="multiple"
onChange={handleChange}
onExpandChange={handleExpandChange}
>
<OptGroup label="Manager" key="manager">
<Option value="zhangsan">zhangsan</Option>
<Option value="lisi">lisi</Option>
</OptGroup>
<OptGroup label="Engineer" key="engineer">
<Option value="xiaoming">xiaoming</Option>
</OptGroup>
</Select>

<Select
defaultValue={['zhangsan', 'xiaohua']}
allowClear
defaultExpandGroupKey
style={{width: 320}}
mode="multiple"
onChange={handleChange}
>
<OptGroup label="Manager" key="manager">
<Option value="zhangsan">zhangsan</Option>
<Option value="lisi">lisi</Option>
<Option value="wanger" disabled>wanger</Option>
</OptGroup>
<OptGroup label="Engineer" key="engineer">
<Option value="xiaoming">xiaoming</Option>
<Option value="xiaohua" disabled>xiaohua</Option>
</OptGroup>
<OptGroup label="Disabled" key="disabled">
<Option value="d1" disabled>d1</Option>
<Option value="d2" disabled>d2</Option>
</OptGroup>
</Select>
</div>
);
}

options 可变​

function App() {
const [opts, setOpts] = useState([{label: 1, value: 1}]);
const onChange = () => {
setOpts([{value: 2, label: 2}, {value: 3, label: 3}]);
};

return (
<div className="acux-demo-row">
<Button onClick={onChange}>change options</Button>
<Select
options={opts}
/>
</div>
);
}

自定义选择器菜单​

自定义选择器下拉菜单,支持新增菜单项和删除菜单项。

function App() {
const {Option} = Select;

const [value, setValue] = useState();
const [newData, setNewData] = useState();
const [data, setData] = useState(['data1', 'data2']);
const [addEdData, setAddEdData] = useState([]);
const [addDisabled, setAddDisabled] = useState(true);

const handleChange = value => {
console.log(value);
setValue(value);
};

const handleDataChange = e => {
const value = e.target.value;
setNewData(value);
};

useEffect(() => {
setAddDisabled(!newData);
return () => setAddDisabled(true);
}, [newData]);

const handleAdd = () => {
setData(data => [...data, newData]);
setAddEdData(addEdData => [...addEdData, newData]);
setNewData();
};

const handleDeleteData = (e, item) => {
const index = data.indexOf(item);
setData(data => {
const cloneData = [...data];
cloneData.splice(index, 1);
return cloneData;
});
const addEdIndex = addEdData.indexOf(item);
setAddEdData(addEdData => {
const cloneAddEdData = [...addEdData];
cloneAddEdData.splice(addEdIndex, 1);
return cloneAddEdData;
});
if (value === item) {
setValue(undefined);
}
e.stopPropagation();
};

return (
<Select
allowClear
style={{width: 240}}
value={value}
dropdownRender={menu => {
return (
<>
{menu}
<div className="acux-demo-row">
<Input
style={{width: "60%"}}
placeholder="请输入"
size="small"
value={newData}
onChange={handleDataChange}
/>
<Button
style={{width: "20%"}}
size="small"
icon={<OutlinedPlus />}
type="text"
disabled={addDisabled}
onClick={handleAdd}
>
新建
</Button>
</div>
</>
);
}}
onChange={handleChange}
>
{data.map(item => {
if (addEdData.includes(item)) {
return (
<Option
value={item}
key={item}
extra={
<OutlinedClose
className={'acux-demo-row'}
onClick={e => handleDeleteData(e, item)}
/>
}
>
{item}
</Option>
);
}
return (
<Option value={item} key={item}>
{item}
</Option>
);
})}
</Select>
);
}

API​

Select props​

参数说明类型默认值
allowClear支持清除booleanfalse
autoClearSearchValue是否在选中项后清空搜索框,只在 mode 为 multiplebooleantrue
autoFocus默认获取焦点booleanfalse
bordered是否有边框booleantrue
clearIcon自定义的多选框清空图标ReactNode--
defaultActiveFirstOption是否默认高亮第一个选项booleantrue
defaultOpen是否默认展开下拉菜单boolean--
defaultValue指定默认选中的条目string〡string[]
number〡number[]
LabeledValue〡LabeledValue[]
--
disabled是否禁用booleanfalse
dropdownClassName下拉菜单的 className 属性string--
dropdownMatchSelectWidth下拉菜单是否和选择器同宽,值为 false 时会关闭虚拟滚动。如果设置为 number,当值小于选择框宽度时会被忽略。boolean〡numbertrue
dropdownRender自定义下拉框内容(originNode: ReactNode) => ReactNode--
dropdownStyle下拉菜单的 style 属性CSSProperties--
filterOption是否根据输入项进行筛选。当其为一个函数时,会接收 inputValue option 两个参数,当 option 符合筛选条件时,应返回 true,反之则返回 falseboolean〡function(inputValue, option)true
optionRender自定义 option 渲染(label: ReactNode, option) => ReactNode--
filterSort搜索时对筛选结果项的排序函数, 类似Array.sort里的 compareFunction(optionA: Option, optionB: Option) => number--
getPopupContainer菜单渲染父节点。默认渲染到 body 上,如果你遇到菜单滚动定位问题,试试修改为滚动的区域,并相对其定位。function(triggerNode)() => document.body
labelInValue是否把每个选项的 label 包装到 value 中,会把 Select 的 value 类型从 string 变为 { value: string, label: ReactNode } 的格式booleanfalse
listHeight设置弹窗滚动高度number256
loading加载中状态booleanfalse
maxTagCount最多显示多少个 tag,响应式模式会对性能产生损耗number〡responsive--
maxTagPlaceholder隐藏 tag 时显示的内容ReactNode〡function(omittedValues)--
maxTagTextLength最大显示的 tag 文本长度number--
menuItemSelectedIcon自定义多选时当前选中的条目图标ReactNode--
mode设置 Select 的模式为多选(默认单选)multiple--
notFoundContent当下拉列表为空时显示的内容ReactNodeNot Found
open是否展开下拉菜单boolean--
optionFilterProp搜索时过滤对应的 option 属性,如设置为 children 表示对内嵌内容进行搜索。若通过 options 属性配置选项内容,建议设置 optionFilterProp="label" 来对内容进行搜索。stringvalue
optionLabelProp回填到选择框的 Option 的属性值,默认是 Option 的子元素。比如在子元素需要高亮效果时,此值可以设为 valuestringchildren
options数据化配置选项内容,相比 jsx 定义会获得更好的渲染性能{label, value}[]--
placeholder选择框默认文本string请选择
placement选择框弹出位置bottomLeft〡bottomRight〡topLeft〡topRightbottomLeft
popupOverflow弹层展示逻辑,默认为可视区域滚动,可配置成滚动区域滚动viewport〡scrollviewport
removeIcon自定义的多选框清除图标ReactNode--
searchValue控制搜索文本string--
showArrow是否显示下拉小箭头booleantrue
showSearch使单选模式可搜索booleanfalse
showTitle是否展示 option titlebooleanfalse
showSelectAll是否展示全选项,多选时有效booleantrue
suffixIcon自定义的选择框后缀图标ReactNode--
groupSelectorRender自定义分组选择器选中项的 label(groupLable, value) => ReactNode--
tagRender自定义 tag 内容 render(props) => ReactNode--
tokenSeparators在 tags 和 multiple 模式下自动分词的分隔符string[]--
value指定当前选中的条目string〡string[]
number〡number[]
LabeledValue〡LabeledValue[]
--
virtual设置 false 时关闭虚拟滚动(可折叠分组模式下,始终关闭虚拟滚动)booleantrue
keepExpand分组始终展开,并且不可操作,只有单选时生效booleanfalse
defaultExpandGroupKey默认展开的分组 key, 为 true 时全部展开,为 false 时全部收起,也可以指定展开组的 key(如果没有设置 key,则为该分组的 index 下标字符串)string[]〡string〡number[]〡number〡booleanfalse
onBlur失去焦点时回调function--
onChange选中 option,或 input 的 value 变化时,调用此函数function(value, option:Option〡Array&lt;Option>)--
onClear清除内容时回调function--
onDeselect取消选中时调用,参数为选中项的 value (或 key) 值,仅在 multiple 或 tags 模式下生效function(string〡number〡LabeledValue)--
onDropdownVisibleChange展开下拉菜单的回调function(open)--
onFocus获得焦点时回调function--
onInputKeyDown按键按下时回调function--
onMouseEnter鼠标移入时回调function--
onMouseLeave鼠标移出时回调function--
onPopupScroll下拉列表滚动时的回调function--
onSearch文本框值变化时回调function(value: string)--
onSelect被选中时调用,参数为选中项的 value (或 key) 值function(string〡number〡LabeledValue, option: Option)--
onExpandChange分组展开收起变化时触发,参数为所有展开项的 keyfunction(key:(string〡number)[])--
注意

如果发现下拉菜单跟随页面滚动,或者需要在其他弹层中触发 Select,请尝试使用 getPopupContainer={triggerNode => triggerNode.parentElement} 将下拉弹层渲染节点固定在触发器的父元素中。

Select Methods​

名称说明
blur()取消焦点
focus()获取焦点

Option props​

参数说明类型默认值
classNameOption 器类名string--
disabled是否禁用booleanfalse
title选中该 Option 后,Select 的 titlestring--
value默认根据此属性值进行筛选string〡number--
extra额外的元素ReactNode--

OptGroup props​

参数说明类型默认值
keyKeystring--
label组名string〡React.Element--