Select 选择器
当选项过多时,使用下拉菜单展示并选择内容。
在版本 2.5.0之后, el-select 的默认宽度更改为 100% 当使用内联形式时,宽度将显示异常。为了保持显示正常, 您需要手动配置 el-select 的宽度 (如: 例子).
基础用法
适用广泛的基础单选 v-model 的值为当前被选中的 el-option 的 value 属性值
export function SelectBasic() { const [value, setValue] = useState<SelectValue>(""); return ( <ElSelect value={value} onChange={setValue} options={BASIC_OPTIONS} placeholder="Select" style={{ width: 240 }} /> );}
Options 属性 2.10.5
el-option 基本用法。您可以通过 props 属性自定义 options 的别名。
export function SelectOptions() { const [value, setValue] = useState<SelectValue>(""); const options: SelectOptionType[] = [ { id: "Option1", label: "Option1" }, { id: "Option2", label: "Option2", disabled: true }, { id: "Option3", label: "Option3" }, { id: "Option4", label: "Option4", disabled: true }, { id: "Option5", label: "Option5" }, ]; return ( <ElSelect value={value} onChange={setValue} options={options} props={{ value: "id", label: "label", options: "options", disabled: "disabled" }} placeholder="Select" style={{ width: 240 }} /> );}
有禁用选项
在 el-option 中,设定 disabled 值为 true,即可禁用该选项
export function SelectDisabledOption() { const [value, setValue] = useState<SelectValue>(""); return ( <ElSelect value={value} onChange={setValue} placeholder="Select" style={{ width: 240 }} options={[ { value: "Option1", label: "Option1" }, { value: "Option2", label: "Option2", disabled: true }, { value: "Option3", label: "Option3" }, { value: "Option4", label: "Option4" }, { value: "Option5", label: "Option5" }, ]} /> );}
禁用状态
禁用整个选择器组件
为 el-select 设置 disabled属性,则整个选择器不可用。
export function SelectDisabled() { const [value, setValue] = useState<SelectValue>(""); return ( <ElSelect value={value} onChange={setValue} disabled placeholder="Select" options={BASIC_OPTIONS} style={{ width: 240 }} /> );}
可清空
您可以使用清除图标来清除选择。
为 el-select 设置 clearable 属性,则可将选择器清空。
export function SelectClearable() { const [value, setValue] = useState<SelectValue>(""); return ( <ElSelect value={value} onChange={setValue} options={BASIC_OPTIONS} clearable placeholder="Select" style={{ width: 240 }} /> );}
尺寸
使用 size 属性改变选择器大小。除了默认大小外,还有另外两个选项: large, small。
export function SelectSize() { const [value, setValue] = useState<SelectValue>(""); return ( <div style={row}> {(["large", "default", "small"] as ComponentSize[]).map((size) => ( <ElSelect key={size} value={value} onChange={setValue} options={BASIC_OPTIONS} size={size} placeholder="Select" style={{ width: 240 }} /> ))} </div> );}
基础多选
多选选择器使用 tag 组件来展示已选中的选项。
为 el-select 设置 multiple 属性即可启用多选,此时 v-model 的值为当前选中值所组成的数组。默认情况下选中值会以 Tag 组件的形式展现,你也可以设置 collapse-tags 属性将它们合并为一段文字。您可以使用 collapse-tags-tooltip 属性来启用鼠标悬停折叠文字以显示具体所选值的行为。
use collapse-tags-tooltip
export function SelectMultiple() { const [value1, setValue1] = useState<SelectValue>([]); const [value2, setValue2] = useState<SelectValue>([]); const [value3, setValue3] = useState<SelectValue>([]); const [value4, setValue4] = useState<SelectValue>([]); return ( <> <div style={{ margin: 16 }}> <p>default</p> <ElSelect value={value1} onChange={setValue1} multiple placeholder="Select" options={BASIC_OPTIONS} style={{ width: 240 }} /> </div> <div style={{ margin: 16 }}> <p>use collapse-tags</p> <ElSelect value={value2} onChange={setValue2} multiple collapseTags placeholder="Select" options={BASIC_OPTIONS} style={{ width: 240 }} /> </div> <div style={{ margin: 16 }}> <p>use collapse-tags-tooltip</p> <ElSelect value={value3} onChange={setValue3} multiple collapseTags collapseTagsTooltip placeholder="Select" options={BASIC_OPTIONS} style={{ width: 240 }} /> </div> <div style={{ margin: 16 }}> <p>use max-collapse-tags</p> <ElSelect value={value4} onChange={setValue4} multiple collapseTags collapseTagsTooltip maxCollapseTags={3} placeholder="Select" options={BASIC_OPTIONS} style={{ width: 240 }} /> </div> </> );}
自定义模板
你可以自定义如何来渲染每一个选项。
将自定义的 HTML 模板插入 el-option 的 slot 中即可。
export function SelectCustomTemplate() { const [value, setValue] = useState<SelectValue>(""); return ( <ElSelect value={value} onChange={setValue} placeholder="Select" options={CITIES} style={{ width: 240 }} > {({ item }) => ( <> <span style={{ float: "left" }}>{String(item.label)}</span> <span style={{ float: "right", color: "var(--el-text-color-secondary)", fontSize: 13, }} > {String(item.value)} </span> </> )} </ElSelect> );}
自定义下拉菜单的头部 2.4.3
您可以自定义下拉菜单的头部。
Use slot to customize the content.
export function SelectCustomHeader() { const [value, setValue] = useState<SelectValue>([]); const selected = Array.isArray(value) ? value : []; const checkAll = selected.length === CITIES.length; const indeterminate = selected.length > 0 && selected.length < CITIES.length; const handleCheckAll = (checked: boolean) => { setValue(checked ? CITIES.map((item) => item.value) : []); }; return ( <ElSelect value={value} onChange={setValue} multiple clearable collapseTags placeholder="Select" maxCollapseTags={1} options={CITIES} style={{ width: 240 }} header={ <ElCheckbox checked={checkAll} indeterminate={indeterminate} onCheckedChange={handleCheckAll} > All </ElCheckbox> } /> );}
自定义下拉菜单的底部 2.4.3
您可以自定义下拉菜单的底部。
使用slot 自定义内容
export function SelectCustomFooter() { const [value, setValue] = useState<SelectValue>([]); const [isAdding, setIsAdding] = useState(false); const [optionName, setOptionName] = useState(""); const [cities, setCities] = useState<SelectOptionType[]>(CITIES); const clear = () => { setOptionName(""); setIsAdding(false); }; const onConfirm = () => { if (optionName) { setCities((prev) => [...prev, { label: optionName, value: optionName }]); clear(); } }; return ( <ElSelect value={value} onChange={setValue} placeholder="Select" options={cities} style={{ width: 240 }} footer={ isAdding ? ( <div> <ElInput className="option-input" value={optionName} onChange={setOptionName} placeholder="input option name" size="small" style={{ width: "100%", marginBottom: 8 }} /> <ElButton type="primary" size="small" onClick={onConfirm}> confirm </ElButton> <ElButton size="small" onClick={clear}>cancel</ElButton> </div> ) : ( <ElButton text bg size="small" onClick={() => setIsAdding(true)}> Add an option </ElButton> ) } /> );}
将选项进行分组
你可以为选项进行分组来区分不同的选项
使用 el-option-group 对备选项进行分组,它的 label 属性为分组名
export function SelectGrouping() { const [value, setValue] = useState<SelectValue>(""); const options: SelectOptionType[] = [ { label: "Popular cities", options: [ { value: "Shanghai", label: "Shanghai" }, { value: "Beijing", label: "Beijing" }, ], }, { label: "City name", options: [ { value: "Chengdu", label: "Chengdu" }, { value: "Shenzhen", label: "Shenzhen" }, { value: "Guangzhou", label: "Guangzhou" }, { value: "Dalian", label: "Dalian" }, ], }, ]; return ( <ElSelect value={value} onChange={setValue} placeholder="Select" options={options} style={{ width: 240 }} /> );}
筛选选项
可以利用筛选功能快速查找选项。
为el-select添加filterable属性即可启用搜索功能。默认情况下,Select 会找出所有 label 属性包含输入值的选项。如果希望使用其他的搜索逻辑,可以通过传入一个 filter-method 来实现。 filter-method 为一个 Function,它会在输入值发生变化时调用,参数为当前输入值。
export function SelectFilterable() { const [value, setValue] = useState<SelectValue>(""); return ( <ElSelect value={value} onChange={setValue} filterable placeholder="Select" options={BASIC_OPTIONS} style={{ width: 240 }} /> );}
远程搜索
输入关键字以从远程服务器中查找数据。
从服务器搜索数据,输入关键字进行查找。为了启用远程搜索,需要将filterable和remote设置为true,同时传入一个remote-method。 remote-method为一个Function,它会在输入值发生变化时调用,参数为当前输入值。需要注意的是,如果 el-option 是通过 v-for 指令渲染出来的,此时需要为 el-option 添加 key 属性,且其值需具有唯一性,比如这个例子中的 item.value。
export function SelectRemoteSearch() { const [value, setValue] = useState<SelectValue>([]); const [options, setOptions] = useState<SelectOptionType[]>([]); const [loading, setLoading] = useState(false); const remoteMethod = (query: string) => { if (!query) { setOptions([]); return; } setLoading(true); setTimeout(() => { setLoading(false); setOptions( REMOTE_LIST.filter((item) => String(item.label).toLowerCase().includes(query.toLowerCase()), ), ); }, 200); }; return ( <div style={wrap}> <div style={{ margin: 16 }}> <p style={{ marginTop: 0 }}>default</p> <ElSelect value={value} onChange={setValue} multiple filterable remote reserveKeyword placeholder="Please enter a keyword" remoteMethod={remoteMethod} loading={loading} options={options} style={{ width: 240 }} /> </div> <div style={{ margin: 16 }}> <p style={{ marginTop: 0 }}>use remote-show-suffix</p> <ElSelect value={value} onChange={setValue} multiple filterable remote reserveKeyword remoteShowSuffix placeholder="Please enter a keyword" remoteMethod={remoteMethod} loading={loading} options={options} style={{ width: 240 }} /> </div> </div> );}
创建新的选项
创建并选中未包含在初始选项中的条目。
通过使用 allow-create 属性,用户可以通过输入框创建新项目。为了使 allow-create 正常工作, filterable 的值必须为 true。本例还使用了 default-first-option 属性,在该属性为 true 的情况下,按下回车就可以选中当前选项列表中的第一个选项,无需使用鼠标或键盘方向键进行定位。
export function SelectAllowCreate() { const [value, setValue] = useState<SelectValue>([]); return ( <ElSelect value={value} onChange={setValue} multiple filterable allowCreate defaultFirstOption reserveKeyword={false} placeholder="Choose tags for your article" options={[ { value: "HTML", label: "HTML" }, { value: "CSS", label: "CSS" }, { value: "JavaScript", label: "JavaScript" }, ]} style={{ width: 240 }} /> );}
使用值键 value-key 属性
如果 Select 的绑定值为对象类型,请务必指定 value-key 作为它的唯一性标识。
通过使用 value-key 属性,可以正确处理带有重复label的数据。这样虽然label 是重复的,但任可通过 id 来确认唯一性。
selected option's description: no select
export function SelectValueKey() { const [value, setValue] = useState<SelectValue>(null); const options: SelectOptionType[] = [ { id: 1, label: "Option A", desc: "Option A - 230506" }, { id: 2, label: "Option B", desc: "Option B - 230506" }, { id: 3, label: "Option C", desc: "Option C - 230506" }, { id: 4, label: "Option A", desc: "Option A - 230507" }, ]; const selected = value && typeof value === "object" && !Array.isArray(value) ? (value as Record<string, unknown>) : undefined; return ( <div style={{ margin: 16 }}> <ElSelect value={value} onChange={setValue} valueKey="id" placeholder="Select" options={options} style={{ width: 240 }} /> <p> selected option's description: {selected ? String(selected.desc) : "no select"} </p> </div> );}
自定义标签 2.5.0
您可以自定义标签。
将自定义的标签插入 el-select 的 slot 中即可。 collapse-tags, collapse-tags-tooltip, max-collapse-tags 在此模式下不生效.
export function SelectCustomTag() { const [value, setValue] = useState<SelectValue>([ "#E63415", "#FF6600", "#FFDE0A", "#1EC79D", "#14CCCC", "#4167F0", "#6222C9", ]); const colors: SelectOptionType[] = [ { value: "#E63415", label: "red" }, { value: "#FF6600", label: "orange" }, { value: "#FFDE0A", label: "yellow" }, { value: "#1EC79D", label: "green" }, { value: "#14CCCC", label: "cyan" }, { value: "#4167F0", label: "blue" }, { value: "#6222C9", label: "purple" }, ]; return ( <ElSelect value={value} onChange={setValue} multiple placeholder="Select" options={colors} style={{ width: 240 }} tag={({ data }) => ( <> {data.map((option) => ( <ElTag key={String(option.value)} color={String(option.value)} style={{ border: "none", aspectRatio: "1" }} /> ))} </> )} > {({ item }) => ( <div style={{ display: "flex", alignItems: "center" }}> <ElTag color={String(item.value)} size="small" style={{ marginRight: 8 }} /> <span style={{ color: String(item.value) }}> {String(item.label)} </span> </div> )} </ElSelect> );}
自定义加载 2.5.2
修改加载区域内容
export function SelectCustomLoading() { const [value, setValue] = useState<SelectValue>([]); const [options, setOptions] = useState<SelectOptionType[]>([]); const [loading, setLoading] = useState(false); const remoteMethod = (query: string) => { if (!query) { setOptions([]); return; } setLoading(true); setTimeout(() => { setLoading(false); setOptions( REMOTE_LIST.filter((item) => String(item.label).toLowerCase().includes(query.toLowerCase()), ), ); }, 1000); }; const loadingSlot = ( <ElIcon className="is-loading"> <Loading /> </ElIcon> ); return ( <div style={wrap}> <div style={{ margin: 16 }}> <p style={{ marginTop: 0 }}>loading icon1</p> <ElSelect value={value} onChange={setValue} multiple filterable remote reserveKeyword placeholder="Please enter a keyword" remoteMethod={remoteMethod} loading={loading} loadingSlot={loadingSlot} options={options} style={{ width: 240 }} /> </div> <div style={{ margin: 16 }}> <p style={{ marginTop: 0 }}>loading icon2</p> <ElSelect value={value} onChange={setValue} multiple filterable remote reserveKeyword placeholder="Please enter a keyword" remoteMethod={remoteMethod} loading={loading} loadingSlot={loadingSlot} options={options} style={{ width: 240 }} /> </div> </div> );}
空值配置2.7.0
若想配置如空字符串为有效值而不是空值,可以配置 empty-values 为 [null, undefined].
如果您想要将清空值更改为 null, 请设置 value-on-clear 为 null
export function SelectEmptyValues() { const [value, setValue] = useState<SelectValue>(""); return ( <ElSelect value={value} onChange={setValue} emptyValues={[null, undefined]} valueOnClear={null} onClear={() => message.info("The clear value is: null")} clearable placeholder="Select" options={[ { value: "", label: "All" }, ...BASIC_OPTIONS, ]} style={{ width: 240 }} /> );}
自定义标签 2.7.4
您可以自定义标签
export function SelectCustomLabel() { const [value1, setValue1] = useState<SelectValue>("Option1"); const [value2, setValue2] = useState<SelectValue>(["Option1"]); const options: SelectOptionType[] = [ { value: "Option1", label: "Label1" }, { value: "Option2", label: "Label2" }, { value: "Option3", label: "Label3" }, { value: "Option4", label: "Label4" }, { value: "Option5", label: "Label5" }, ]; return ( <div style={row}> <ElSelect value={value1} onChange={setValue1} placeholder="Select" options={options} clearable style={{ width: 240 }} label={({ label, value }) => ( <> <span>{String(label)}: </span> <span style={{ fontWeight: "bold" }}>{String(value)}</span> </> )} /> <ElSelect value={value2} onChange={setValue2} placeholder="Select" options={options} clearable multiple style={{ width: 240 }} label={({ label, value }) => ( <> <span>{String(label)}: </span> <span style={{ fontWeight: "bold" }}>{String(value)}</span> </> )} /> </div> );}
Select API
Select Attributes
| 属性名 | 说明 | 类型 | 默认值 |
|---|
| value | 选中项的值,多选时为数组 | string / number / boolean / object / array | — |
| options | 选项数据,分组项通过 options 子数组嵌套 | array | [] |
| props | 选项字段别名 | object | — |
| value-key | 选中值对象作为唯一标识的字段名 | string | value |
| multiple | 是否多选 | boolean | false |
| disabled | 是否禁用 | boolean | false |
| size | 尺寸 | enum | — |
| clearable | 是否可清空 | boolean | false |
| clear-icon | 自定义清空图标 | ReactNode | — |
| filterable | 是否可搜索 | boolean | false |
| filter-method | 自定义过滤方法 | Function | — |
| remote | 是否远程搜索,需同时开启 filterable | boolean | false |
| remote-method | 远程搜索方法 | Function | — |
| remote-show-suffix | 远程搜索时是否显示后缀图标 | boolean | false |
| debounce | 远程搜索防抖时长(毫秒) | number | 300 |
| loading | 是否正在加载数据 | boolean | false |
| loading-text | 加载中文案 | string | 加载中 |
| reserve-keyword | 多选且可搜索时是否保留关键词 | boolean | true |
| default-first-option | 回车时是否选中第一个匹配项 | boolean | false |
| allow-create | 是否允许创建新选项,需开启 filterable | boolean | false |
| automatic-dropdown | 非搜索模式下聚焦是否自动展开 | boolean | false |
| multiple-limit | 多选数量上限,0 表示不限 | number | 0 |
| collapse-tags | 多选时是否折叠标签 | boolean | false |
| collapse-tags-tooltip | 折叠标签是否在悬停时展示全部 | boolean | false |
| max-collapse-tags | 折叠时最多展示的标签数 | number | 1 |
| tag-type | 标签类型 | enum | info |
| tag-effect | 标签主题 | enum | light |
| placeholder | 占位文本 | string | 请选择 |
| no-data-text | 无选项时的文案 | string | 无数据 |
| no-match-text | 搜索无匹配项时的文案 | string | 无匹配数据 |
| popper-class / popper-style | 下拉浮层的类名与样式 | string / object | — |
| teleported | 下拉是否传送到 body | boolean | true |
| persistent | 下拉关闭后是否保留 DOM | boolean | true |
| effect | 浮层主题 | enum | light |
| placement | 下拉位置 | string | bottom-start |
| fallback-placements | 下拉翻转兜底位置 | array | — |
| show-arrow | 是否显示下拉箭头 | boolean | true |
| offset | 下拉与输入框的间距 | number | 12 |
| fit-input-width | 下拉宽度是否与输入框一致,或传固定数值 | boolean / number | true |
| suffix-icon | 自定义后缀图标 | ReactNode | — |
| empty-values | 空值集合 | array | — |
| value-on-clear | 清空后的返回值 | string / number / boolean / Function / null | — |
| scrollbar-always-on | 是否总是显示滚动条 | boolean | false |
| validate-event | 值变化时是否触发表单校验 | boolean | true |
| name | 原生 input name | string | — |
| id | 原生 input id | string | — |
| autocomplete | 原生 autocomplete | string | off |
| tabindex | 原生 input tabindex | string / number | 0 |
| aria-label | 无障碍标签 | string | — |
| class-name / style | 根元素类名与样式 | string / object | — |
Select Events
| 事件名 | 说明 | 参数 |
|---|
| onChange | 选中值变化 | Function |
| onVisibleChange | 下拉可见性变化 | Function |
| onRemoveTag | 多选移除标签 | Function |
| onClear | 点击清空 | Function |
| onFocus | 获得焦点 | Function |
| onBlur | 失去焦点 | Function |
| onEndReached | 滚动到边界 | Function |
Select Slots(React render props)
| 名称 | 说明 | 参数 |
|---|
| children | 自定义选项内容 | Function |
| label | 自定义选中值与标签文案 | Function |
| tag | 自定义多选标签 | Function |
| header | 下拉头部 | ReactNode |
| footer | 下拉底部 | ReactNode |
| loadingSlot | 自定义加载内容 | ReactNode |
| empty | 自定义空数据内容 | ReactNode |
| prefix | 输入框前缀 | ReactNode |
Select Exposes
| 方法 | 说明 | 参数 |
|---|
| focus | 使选择器获得焦点 | — |
| blur | 使选择器失去焦点 | — |
| scrollTo | 滚动到指定选项 | Function |
| selectedLabel | 当前选中项文案,多选返回数组 | — |
SelectOptionType
| 字段 | 说明 | 类型 | 默认值 |
|---|
| value | 选项值,字段名可通过 props.value 改写 | string / number / boolean / object | — |
| label | 选项显示文本,字段名可通过 props.label 改写 | ReactNode | — |
| disabled | 是否禁用该项,字段名可通过 props.disabled 改写 | boolean | false |
| options | 分组选项的子选项,字段名可通过 props.options 改写 | array | — |
| type | 在内置类型中固定为 Group 时渲染为分组标题 | string | — |
| created | 由 allow-create 生成的临时选项 | boolean | false |