---
localeCode: zh-CN
order: 27
category: 输入类
title: Select 选择器
icon: doc-select
width: 60%
brief: 用户可以通过 Select 选择器从一个选项集合中去选中一个或多个选项,并呈现最终选择结果
---
## 代码演示
### 如何引入
```jsx import
import { Select } from '@douyinfe/semi-ui';
const Option = Select.Option;
```
Select的直接子元素必须为 Option 或者 OptGroup,不允许为其他Element
### 基本使用
每个 Option 标签都必须声明 value 属性,Option 的 children 或 label 将会被渲染至下拉列表中
```jsx live=true
import React from 'react';
import { Select } from '@douyinfe/semi-ui';
() => (
<>
>
);
```
### 以数组形式传入 Option
可以直接通过`optionList`传入一个对象数组,每个对象必须包含 value/label 属性(当然其他属性也可以通过此方式传入)
```jsx live=true
import React from 'react';
import { Select } from '@douyinfe/semi-ui';
() => {
const list = [
{ value: 'abc', label: '抖音', otherKey:0 },
{ value: 'hotsoon', label: '火山小视频', disabled: true, otherKey: 1 },
{ value: 'jianying', label: '剪映', otherKey: 2 },
{ value: 'toutiao', label: '今日头条', otherKey: 3 },
];
return (
);
};
```
### 多选
配置`multiple`属性,可以支持多选
配置 `maxTagCount` 可以限制已选项展示的数量,超出部分将以+N 的方式展示
配置 `max` 属性可限制最大可选的数量,超出最大限制数量后无法选中,同时会触发`onExceed`回调
```jsx live=true
import React from 'react';
import { Select } from '@douyinfe/semi-ui';
() => (
<>
>
);
```
### 分组
分组功能 v0.31.0 后提供
用 OptGroup 进行分组(分组功能仅支持通过jsx方式声明children使用,不支持optionList方式传入)
1. OptGroup必须为Select的直接子元素,不允许有Fragment或DIV等其他元素阻隔
2. 若Select的children需要动态更新,OptGroup上的key也需要进行更新,否则Select无法识别
```jsx live=true
import React from 'react';
import { Select } from '@douyinfe/semi-ui';
() => (
);
```
```jsx live=true
import React from 'react';
import { Select } from '@douyinfe/semi-ui';
() => {
const data = [
{
label: 'Asia',
children: [
{ value: 'a-1', label: 'China' },
{ value: 'a-2', label: 'Koera' },
]
},
{
label: 'Europe',
children: [
{ value: 'b-1', label: 'Germany' },
{ value: 'b-2', label: 'France' },
]
},
{
label: 'South America',
children: [
{ value: 'c-1', label: 'Peru' },
]
}
];
return (
);
};
```
### 不同尺寸
通过Size控制选择器的大小尺寸: `small` / `default` / `large`
```jsx live=true
import React from 'react';
import { Select } from '@douyinfe/semi-ui';
() => (
<>
>
);
```
### 不同校验状态样式
validateStatus: default / warning / error
仅影响背景颜色等样式表现
```jsx live=true
import React from 'react';
import { Select } from '@douyinfe/semi-ui';
() => (
<>
>
);
```
### 配置前缀、后缀、清除按钮
- 可以通过`prefix`传入选择框前缀,通过`suffix`传入选择框后缀,可以为文本或者 ReactNode
当 prefix、suffix 传入的内容为文本或者 Icon 时,会自动带上左右间隔,若为自定义 ReactNode,则左右间隔为 0
- 通过`showClear`控制清除按钮是否展示
- 通过`showArrow`控制右侧下拉箭头是否展示
```jsx live=true
import React from 'react';
import { Select } from '@douyinfe/semi-ui';
import { IconVigoLogo, IconGift } from '@douyinfe/semi-icons';
() => (
<>
}
showClear={true}
>
抖音
火山
剪映
西瓜视频
}
suffix={}
showArrow={false}
>
抖音
火山
剪映
西瓜视频
>
);
```
### 内嵌标签
通过设置`insetLabel`,你可以给 Select 设置 label,可以传入 string 或者 ReactNode
当传入类型为 ReactNode 时,注意要自行处理 label 与文本之间的间隔
```jsx live=true
import React from 'react';
import { Select } from '@douyinfe/semi-ui';
() => {
const list = [
{ value: 'abc', label: '抖音' },
{ value: 'hotsoon', label: '火山小视频' },
{ value: 'jianying', label: '剪映' },
{ value: 'toutiao', label: '今日头条' },
];
return (
<>
>
);
};
```
### 在顶部/底部渲染附加项
我们在弹出层顶部、底部分别预留了插槽,当你需要在弹出层中添加自定义 node 时
可以通过`innerBottomSlot`或者`outerBottomSlot`传入,自定义 node 将会被渲染在弹出层底部;可以通过`innerTopSlot`或者`outerTopSlot`传入,自定义 node 将会被渲染在弹出层顶部。
- `innerTopSlot` 和 `innerBottomSlot`将会被渲染在 optionList 内部,当滚动到 optionList 顶部/底部时展现
- `outerTopSlot` 和 `outerBottomSlot`将会被渲染为与 optionList 平级,无论 optionList 是否滚动,都会始终展现
```jsx live=true
import React from 'react';
import { Select } from '@douyinfe/semi-ui';
() => {
let innerSlotStyle = {
backgroundColor: 'var(--color-white)',
height: '36px',
display: 'flex',
alignItems: 'center',
cursor: 'pointer',
paddingLeft: 32,
borderTop: '1px solid var(--semi-color-border)',
borderRadius: '0 0 6px 6px',
color: 'var(--semi-color-link)',
};
let innerSlotNode = (
点击加载更多
);
let outSlotStyle = {
backgroundColor: 'var(--semi-color-fill-0)',
height: '36px',
display: 'flex',
paddingLeft: 32,
color: 'var(--semi-color-link)',
alignItems: 'center',
cursor: 'pointer',
borderTop: '1px solid var(--semi-color-border)',
borderRadius: '0 0 6px 6px',
};
let outSlotNode = (
未找到应用?
);
return (
outerBottomSlot:
innerBottomSlot:
);
};
```
通过 outerTopSlot 将内容插入顶部插槽
```jsx live=true
import React from 'react';
import { Select } from '@douyinfe/semi-ui';
() => {
const list = {
component: [
{ value: 'select', label: '选择器' },
{ value: 'tabs', label: '标签' },
{ value: 'avatar', label: '头像' },
{ value: 'button', label: '按钮' },
],
design: [
{ value: 'color', label: '颜色' },
{ value: 'dark', label: '暗色模式' },
{ value: 'icon', label: '图标' },
{ value: 'font', label: '字体' },
],
feedback: [
{ value: 'faq', label: '常见问题' },
{ value: 'join', label: '加入用户群' },
{ value: 'hornbill', label: '犀鸟反馈问题' },
],
};
const [key, setKey] = useState('component');
const [value, setValue] = useState({ value: 'faq', label: '常见问题' },);
const handleTabClick = (itemKey) => {
setKey(itemKey);
};
const tabStyle = {
cursor: 'pointer',
marginRight: 12,
paddingBottom: 4,
};
const tabActiveStyle = {
...tabStyle,
borderBottom: '1px solid var(--semi-color-primary)',
fontWeight: 700,
};
const tabWrapper = {
display: 'flex',
paddingTop: 8,
paddingLeft: 32,
borderBottom: '0.5px solid var(--semi-color-border)'
};
const tabOptions = [
{ itemKey: 'component', label: '组件' },
{ itemKey: 'design', label: '设计' },
{ itemKey: 'feedback', label: '反馈' },
];
const outerTopSlotNode = (
{
tabOptions.map((item, index) => {
style = item.itemKey === key ? tabActiveStyle : tabStyle;
return (
handleTabClick(item.itemKey)}>{item.label}
);
})
}
);
return (