Select 选择器
用于从选项集合中选择单个或多个值,适合枚举、状态、人员、城市、分类等字段。
基础用法
当前值:pending,清除次数:0
vue
<template>
<x-select v-model="value" placeholder="请选择" allow-clear @clear="clearCount++">
<x-select-option value="pending">待处理</x-select-option>
<x-select-option value="processing">处理中</x-select-option>
<x-select-option value="done">已完成</x-select-option>
<x-select-option value="disabled" disabled>禁用项</x-select-option>
</x-select>
<p>当前值:{{ value || '未选择' }},清除次数:{{ clearCount }}</p>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('pending');
const clearCount = ref(0);
</script>多选
请选择成员当前值:design, frontend
vue
<template>
<x-select
v-model="values"
multiple
allow-clear
:max-tag-count="2"
placeholder="请选择成员"
>
<x-select-option value="design" :tag-props="{ color: 'blue' }">设计</x-select-option>
<x-select-option value="frontend" :tag-props="{ color: 'green' }">前端</x-select-option>
<x-select-option value="backend">后端</x-select-option>
<x-select-option value="qa">测试</x-select-option>
</x-select>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const values = ref(['design', 'frontend']);
</script>搜索和自定义过滤
支持中文和英文拼写过滤
vue
<template>
<x-select
v-model="city"
allow-search
:options="cities"
:filter-option="filterCity"
placeholder="搜索城市"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const city = ref('');
const cities = [
{ label: '北京 Beijing', value: 'beijing' },
{ label: '上海 Shanghai', value: 'shanghai' },
{ label: '广州 Guangzhou', value: 'guangzhou' },
{ label: '深圳 Shenzhen', value: 'shenzhen' },
];
const filterCity = (input: string, option: { label?: string }) =>
option.label?.toLowerCase().includes(input.toLowerCase()) ?? false;
</script>允许创建
输入后选择新标签当前标签:vue
vue
<template>
<x-select v-model="tags" multiple allow-create placeholder="输入后选择新标签">
<x-select-option value="vue">Vue</x-select-option>
<x-select-option value="typescript">TypeScript</x-select-option>
<x-select-option value="vite">Vite</x-select-option>
</x-select>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const tags = ref(['vue']);
</script>选择数量限制
产品尝试选择第 3 项触发限制
vue
<template>
<x-select
v-model="members"
multiple
:limit="2"
:options="memberOptions"
placeholder="最多选择 2 项"
@exceed-limit="message = '最多只能选择 2 项'"
/>
<p>{{ message }}</p>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const members = ref(['pm']);
const message = ref('');
const memberOptions = [
{ label: '产品', value: 'pm' },
{ label: '设计', value: 'design' },
{ label: '前端', value: 'frontend' },
{ label: '后端', value: 'backend' },
];
</script>通过 options 渲染
北京 Beijing当前值:beijing
vue
<template>
<x-select v-model="value" :options="options" placeholder="请选择城市" />
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('beijing');
const options = [
{ label: '北京', value: 'beijing' },
{ label: '上海', value: 'shanghai' },
{ label: '禁用项', value: 'disabled', disabled: true },
];
</script>自定义字段名
北京
vue
<template>
<x-select
v-model="city"
:options="options"
:field-names="{ value: 'id', label: 'name', disabled: 'locked' }"
placeholder="请选择城市"
/>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const city = ref('bj');
const options = [
{ id: 'bj', name: '北京' },
{ id: 'sh', name: '上海' },
{ id: 'gz', name: '广州', locked: true },
];
</script>选项分组
vue
<template>
<x-select v-model="city" placeholder="请选择城市">
<x-select-option-group label="华北">
<x-select-option value="beijing">北京</x-select-option>
<x-select-option value="tianjin">天津</x-select-option>
</x-select-option-group>
<x-select-option-group label="华东">
<x-select-option value="shanghai">上海</x-select-option>
<x-select-option value="hangzhou">杭州</x-select-option>
</x-select-option-group>
</x-select>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const city = ref('');
</script>状态和尺寸
vue
<template>
<x-space direction="vertical">
<x-select v-model="value" size="small" :options="options" placeholder="小尺寸" />
<x-select v-model="value" :options="options" disabled placeholder="禁用状态" />
<x-select v-model="value" :options="options" error placeholder="错误状态" />
<x-select v-model="value" :options="options" loading placeholder="加载中" />
<x-select v-model="value" :options="options" :bordered="false" placeholder="无边框" />
</x-space>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('');
const options = [
{ label: '选项 A', value: 'a' },
{ label: '选项 B', value: 'b' },
];
</script>自定义内容和插槽
状态
vue
<template>
<x-select v-model="value" placeholder="请选择">
<template #prefix>状态</template>
<template #header>
<div style="padding: 8px 12px">常用状态</div>
</template>
<template #footer>
<div style="padding: 8px 12px">没有合适选项时可联系管理员</div>
</template>
<template #label="{ data }">
{{ data.label }} / {{ data.value }}
</template>
<x-select-option value="pending" label="待处理">
待处理
<template #suffix>3</template>
</x-select-option>
<x-select-option value="done" label="已完成">
已完成
<template #suffix>8</template>
</x-select-option>
</x-select>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('pending');
</script>虚拟列表和滚动事件
继续滚动查看更多
vue
<template>
<x-select
v-model="value"
:options="options"
:virtual-list-props="{ height: 200 }"
placeholder="大量数据"
@dropdown-reach-bottom="reached = true"
/>
<p>{{ reached ? '已滚动到底部' : '继续滚动查看更多' }}</p>
</template>
<script setup lang="ts">
import { ref } from 'vue';
const value = ref('');
const reached = ref(false);
const options = Array.from({ length: 100 }, (_, index) => ({
label: `选项 ${index + 1}`,
value: index + 1,
}));
</script>按需导入
ts
import { Select, SelectOption, SelectOptionGroup, SelectDropdown } from 'x-next';Select Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
multiple | 是否多选 | boolean | false |
modelValue | 绑定值 | string | number | boolean | object | array | undefined |
defaultValue | 默认值,非受控模式 | string | number | boolean | object | array | 单选 '',多选 [] |
inputValue | 搜索输入值 | string | - |
defaultInputValue | 默认搜索输入值 | string | '' |
size | 选择器尺寸 | 'mini' | 'small' | 'medium' | 'large' | 跟随全局配置 |
placeholder | 占位提示 | string | - |
loading | 是否加载中 | boolean | false |
disabled | 是否禁用 | boolean | false |
error | 是否错误状态 | boolean | false |
allowClear | 是否允许清空 | boolean | false |
allowSearch | 是否允许搜索 | boolean | { retainInputValue?: boolean } | 单选 false,多选 true |
allowCreate | 是否允许创建新选项 | boolean | false |
maxTagCount | 多选最多显示标签数量,0 不限制 | number | 0 |
popupContainer | 弹出层挂载容器 | string | HTMLElement | - |
bordered | 是否显示边框 | boolean | true |
popupVisible | 弹出层显示状态 | boolean | undefined |
defaultPopupVisible | 默认弹出层显示状态 | boolean | false |
unmountOnClose | 关闭时是否销毁弹出层 | boolean | false |
filterOption | 是否过滤选项或自定义过滤方法 | boolean | function | true |
options | 选项数据 | Array<string | number | boolean | SelectOptionData> | [] |
virtualListProps | 虚拟列表配置,传入后开启虚拟滚动 | object | - |
triggerProps | 下拉触发器配置 | object | - |
formatLabel | 格式化显示内容 | (data) => string | - |
fallbackOption | 自定义值不存在时的兜底选项 | boolean | function | true |
showExtraOptions | 是否显示额外选项 | boolean | true |
valueKey | 对象值的唯一键字段 | string | 'value' |
searchDelay | 搜索事件触发延迟 | number | 500 |
limit | 多选最多选择数量,0 不限制 | number | 0 |
fieldNames | 自定义选项字段名 | object | - |
scrollbar | 是否开启滚动条或滚动条配置 | boolean | object | true |
showHeaderOnEmpty | 空状态时是否显示 header | boolean | false |
showFooterOnEmpty | 空状态时是否显示 footer | boolean | false |
tagNowrap | 多选标签内容是否不换行 | boolean | false |
Select Events
| 事件名 | 说明 | 回调参数 |
|---|---|---|
update:modelValue | 值更新时触发 | value |
update:inputValue | 搜索输入值更新时触发 | inputValue |
update:popupVisible | 弹出层显示状态更新时触发 | visible |
change | 值变化时触发 | value |
input-value-change | 输入值变化时触发 | inputValue |
popup-visible-change | 弹出层显示状态变化时触发 | visible |
clear | 点击清除按钮时触发 | event |
remove | 删除多选标签时触发 | removed |
search | 用户搜索时触发 | inputValue |
dropdown-scroll | 下拉菜单滚动时触发 | event |
dropdown-reach-bottom | 下拉菜单滚动到底部时触发 | event |
exceed-limit | 多选超过数量限制时触发 | value, event |
Select Slots
| 插槽名 | 说明 |
|---|---|
empty | 空状态内容 |
option | 自定义选项内容 |
label | 自定义选择框显示内容 |
header | 下拉框页头 |
footer | 下拉框页脚 |
arrow-icon | 箭头图标 |
loading-icon | 加载中图标 |
search-icon | 搜索图标 |
prefix | 前缀元素 |
trigger | 自定义触发元素 |
SelectOption Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
value | 选项值,不填时从内容获取 | string | number | boolean | object | undefined |
label | 选项标签,不填时从内容获取 | string | - |
disabled | 是否禁用 | boolean | false |
tagProps | 多选时展示标签的属性 | object | - |
index | 手动指定选项 index | number | - |
SelectOption Slots
| 插槽名 | 说明 |
|---|---|
default | 选项内容 |
icon | 选项图标 |
suffix | 选项后缀 |
SelectOptionGroup Props
| 参数 | 说明 | 类型 | 默认值 |
|---|---|---|---|
label | 选项组标题 | string | - |
SelectOptionGroup Slots
| 插槽名 | 说明 |
|---|---|
default | 选项组内容 |
label | 自定义选项组标题 |