Combobox 组合框
新粗野主义风格的可搜索选择组件。通过 multiple 属性切换单选和多选模式。
预览
加载状态
点击按钮触发 loading,列表底部显示 Spinner。
创建选项(单选)
输入无匹配项时显示「创建」选项,创建后关闭下拉。
创建选项(多选)
创建后不关闭下拉,可继续创建多项。
安装
pnpm dlx brutx-vue@latest add combobox用法
单选模式
<script setup>
import { ref } from 'vue'
import { Combobox } from 'brutx-ui-vue'
const selected = ref(undefined)
const options = [
{ value: 'vue', label: 'Vue' },
{ value: 'react', label: 'React' },
{ value: 'angular', label: 'Angular' },
{ value: 'svelte', label: 'Svelte' },
]
</script>
<template>
<Combobox
v-model="selected"
:options="options"
placeholder="Select a framework..."
search-placeholder="Search frameworks..."
/>
</template>多选模式
<script setup>
import { ref } from 'vue'
import { Combobox } from 'brutx-ui-vue'
const selected = ref([])
const options = [
{ value: 'vue', label: 'Vue' },
{ value: 'react', label: 'React' },
{ value: 'angular', label: 'Angular' },
{ value: 'svelte', label: 'Svelte' },
]
</script>
<template>
<Combobox
v-model="selected"
:options="options"
multiple
placeholder="Select frameworks..."
:max-display="3"
/>
</template>加载状态
设置 loading 为 true 时,下拉列表底部显示 Spinner,适用于异步加载选项的场景。
<script setup>
import { ref } from 'vue'
import { Combobox } from 'brutx-ui-vue'
const loading = ref(false)
const options = ref([])
async function handleOpen() {
loading.value = true
options.value = await fetchOptions()
loading.value = false
}
</script>
<template>
<Combobox v-model="selected" :options="options" :loading="loading" />
</template>创建选项
设置 creative 为 true 时,若搜索无匹配项且输入框非空,列表顶部显示「创建 '{query}'」选项(文本取自 locale combobox.create)。点击该项触发 create 事件,参数为去除首尾空格后的搜索文本(显示与事件参数均使用 trim 后的查询,避免创建出带脏空格的 value/label)。
Combobox(单选):创建后关闭下拉。Combobox(multiple):创建后不关闭下拉,便于继续选择或创建多项。
<script setup>
import { ref } from 'vue'
import { Combobox } from 'brutx-ui-vue'
const selected = ref(undefined)
const options = ref([
{ value: 'vue', label: 'Vue' },
{ value: 'react', label: 'React' },
])
function handleCreate(value) {
options.value.push({ value: value.toLowerCase(), label: value })
selected.value = value.toLowerCase()
}
</script>
<template>
<Combobox
v-model="selected"
:options="options"
creative
@create="handleCreate"
/>
</template>数据类型
interface ComboboxOption {
value: string
label: string
disabled?: boolean
}API 参考
| 名称 | 类型 | 默认值 | 说明 |
|---|---|---|---|
options必填 | ComboboxOption[] | — | 可供选择的选项列表;每项含字符串 value、显示 label 和可选 disabled。 |
详情声明类型ComboboxOption[] 关联类型 ComboboxOption 类型定义 — ComboboxOptionexport interface ComboboxOption {
value: string
label: string
disabled?: boolean
}默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
modelValue | string | string[] | undefined | undefined | 当前选中的字符串值或值数组,通过 v-model 绑定;多选时使用字符串数组。 |
详情声明类型string | string[] | undefined 默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
multiple | boolean | undefined | false | 启用多选模式后,用户可同时选择多个选项。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
open | boolean | undefined | undefined | 下拉面板展开状态;传入后组件处于受控模式,父组件需回写 update:open 才能应用切换。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
placeholder | string | undefined | undefined | 触发器未选择内容时的占位文本;未提供时按单选或多选模式读取本地化文案。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
searchPlaceholder | string | undefined | undefined | 下拉面板内搜索输入框的占位文本;未提供时读取本地化文案。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
emptyText | string | undefined | undefined | 搜索没有匹配选项时显示的文本;未提供时读取本地化文案。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
disabled | boolean | undefined | false | 禁用触发器以及选项交互。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
loading | boolean | undefined | false | 显示加载状态,用于异步准备或刷新选项时反馈等待。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
creative | boolean | undefined | false | 没有匹配项且搜索文本非空时显示创建选项;组件仅发出 create,不会自行写入 modelValue。 |
详情声明类型boolean | undefined 字面量
默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
maxDisplay | number | undefined | 3 | 多选时触发器最多展示的选中标签数;超出部分汇总为数量提示。 |
详情声明类型number | undefined 默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
ariaLabel | string | undefined | undefined | 设置组合框触发器的无障碍名称。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
class | string | undefined | undefined | 追加到组合框根容器的自定义 CSS 类。 |
详情声明类型string | undefined 默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
iconSize | IconSize | undefined | "md" | 设置触发器下拉指示图标的尺寸。 |
详情声明类型IconSize | undefined 字面量
关联类型 IconSize 类型定义 — IconSizeexport type IconSize = NonNullable<VariantProps<typeof iconSizeVariants>['size']> 默认值详情
来源packages/ui/src/components/combobox/Combobox.vue | |||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
@update:modelValue | [value: string | string[] | undefined] | 选择值变化时发出新值;多选模式发出字符串数组,单选再次选择当前项时发出 undefined。 |
详情声明类型[value: string | string[] | undefined] 来源packages/ui/src/components/combobox/Combobox.vue | ||
@update:open | [value: boolean] | 下拉面板请求展开或关闭时发出目标布尔状态。 |
详情声明类型[value: boolean] 字面量
来源packages/ui/src/components/combobox/Combobox.vue | ||
@create | [value: string] | 用户选择创建操作时发出去除首尾空白的搜索文本;新选项和值由调用方写入。 |
详情声明类型[value: string] 来源packages/ui/src/components/combobox/Combobox.vue | ||
| 名称 | 签名或类型 | 说明 |
|---|---|---|
searchQuery | string | 当前搜索输入文本;面板关闭或单选完成后会清空。 |
详情声明类型string 来源packages/ui/src/components/combobox/Combobox.vue | ||
selectedValue | string | string[] | undefined | 当前 modelValue 的只读计算值。 |
详情声明类型string | string[] | undefined 来源packages/ui/src/components/combobox/Combobox.vue | ||
focus | () => void | undefined | 将键盘焦点移动到组合框触发器。 |
详情声明类型() => void | undefined 来源packages/ui/src/components/combobox/Combobox.vue | ||
open | WritableComputedRef<boolean, boolean> | 可读写的下拉展开状态;设置为 true 可打开面板,受控模式仍需父组件回写更新。 |
详情声明类型WritableComputedRef<boolean, boolean> 字面量
来源packages/ui/src/components/combobox/Combobox.vue | ||
交互
选项遵循 Neo-Brutalist 视觉语言:
- 高亮上浮:鼠标悬停或键盘
↑/↓导航聚焦选项时,选项向左上方偏移(-translate-x-0.5 -translate-y-0.5)并显示大阴影(shadow-brutal-lg),形成「浮起」效果。两种触发方式共享同一视觉反馈,确保键盘用户与鼠标用户获得一致体验。 - 按下盖影:点击选项时向右下位移(
--brutal-shadow-offset-*)并去除阴影,落回阴影位置形成「按压」反馈。
上浮样式由共享变体
brutalHighlightLift提供,与Select选项的brutalHoverLift保持视觉一致;区别在于触发机制——Combobox 绑定data-[highlighted=true](兼容键盘高亮),Select 绑定hover:。
可访问性
- 键盘操作:支持
↑/↓上下移动焦点,Enter选中当前项,Escape关闭下拉 - ARIA 属性:通过
ariaLabel属性提供无障碍标签
程序化控制
通过 ref 获取组件实例后,可读取 API 参考中列出的状态,并调用焦点方法。
<script setup>
import { ref } from 'vue'
import { Combobox } from 'brutx-ui-vue'
const comboboxRef = ref(null)
function openDropdown() {
comboboxRef.value?.open = true
}
</script>
<template>
<Combobox ref="comboboxRef" v-model="selected" :options="options" />
<button @click="openDropdown">Open</button>
</template>常见问题
Q: 单选模式下再次点击已选中的选项为什么没有反应?
A: 在 Combobox 单选模式下,再次点击已选中的选项会取消选中(值变为 undefined)。这是设计行为,用于支持清除选择。如果不需要此行为,可以在父组件中监听 update:modelValue 事件,当值变为 undefined 时恢复为之前的值。
Q: 如何实现异步加载选项?
A: 将 loading 设为 true 显示加载状态,在数据加载完成后更新 options 并将 loading 设为 false。可以结合下拉展开事件来触发数据加载,避免一次性加载所有数据。
Q: creative 模式下创建的新选项如何持久化?
A: 组件本身不持久化创建的选项。需要在 create 事件的处理函数中手动将新选项添加到 options 数组中,并同步更新 modelValue。如需持久化存储,可在事件处理中调用后端接口或写入本地存储。