组合框
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxAnchor, ComboboxContent, ComboboxEmpty, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxLabel, ComboboxRoot, ComboboxSeparator, ComboboxTrigger, ComboboxViewport } from 'radix-vue'
import { Icon } from '@iconify/vue'
const v = ref('')
const options = ['Apple', 'Banana', 'Blueberry', 'Grapes', 'Pineapple']
const vegetables = ['Aubergine', 'Broccoli', 'Carrot', 'Courgette', 'Leek']
</script>
<template>
<ComboboxRoot
v-model="v"
class="relative"
>
<ComboboxAnchor class="min-w-[160px] inline-flex items-center justify-between rounded px-[15px] text-[13px] leading-none h-[35px] gap-[5px] bg-white text-grass11 shadow-[0_2px_10px] shadow-black/10 hover:bg-mauve3 focus:shadow-[0_0_0_2px] focus:shadow-black data-[placeholder]:text-grass9 outline-none">
<ComboboxInput
class="!bg-transparent outline-none text-grass11 h-full selection:bg-grass5 placeholder-mauve8"
placeholder="Placeholder..."
/>
<ComboboxTrigger>
<Icon
icon="radix-icons:chevron-down"
class="h-4 w-4 text-grass11"
/>
</ComboboxTrigger>
</ComboboxAnchor>
<ComboboxContent class="absolute z-10 w-full mt-2 min-w-[160px] bg-white overflow-hidden rounded shadow-[0px_10px_38px_-10px_rgba(22,_23,_24,_0.35),_0px_10px_20px_-15px_rgba(22,_23,_24,_0.2)] will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade">
<ComboboxViewport class="p-[5px]">
<ComboboxEmpty class="text-mauve8 text-xs font-medium text-center py-2" />
<ComboboxGroup>
<ComboboxLabel class="px-[25px] text-xs leading-[25px] text-mauve11">
Fruits
</ComboboxLabel>
<ComboboxItem
v-for="(option, index) in options"
:key="index"
class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] pr-[35px] pl-[25px] relative select-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:outline-none data-[highlighted]:bg-grass9 data-[highlighted]:text-grass1"
:value="option"
>
<ComboboxItemIndicator
class="absolute left-0 w-[25px] inline-flex items-center justify-center"
>
<Icon icon="radix-icons:check" />
</ComboboxItemIndicator>
<span>
{{ option }}
</span>
</ComboboxItem>
<ComboboxSeparator class="h-[1px] bg-grass6 m-[5px]" />
</ComboboxGroup>
<ComboboxGroup>
<ComboboxLabel
class="px-[25px] text-xs leading-[25px] text-mauve11"
>
Vegetables
</ComboboxLabel>
<ComboboxItem
v-for="(option, index) in vegetables"
:key="index"
class="text-[13px] leading-none text-grass11 rounded-[3px] flex items-center h-[25px] pr-[35px] pl-[25px] relative select-none data-[disabled]:text-mauve8 data-[disabled]:pointer-events-none data-[highlighted]:outline-none data-[highlighted]:bg-grass9 data-[highlighted]:text-grass1"
:value="option"
>
<ComboboxItemIndicator
class="absolute left-0 w-[25px] inline-flex items-center justify-center"
>
<Icon icon="radix-icons:check" />
</ComboboxItemIndicator>
<span>
{{ option }}
</span>
</ComboboxItem>
</ComboboxGroup>
</ComboboxViewport>
</ComboboxContent>
</ComboboxRoot>
</template>
特点
- 可以是受控的或不受控的。
- 提供 2 种定位模式。
- 支持项目、标签、项目组。
- 焦点完全管理。
- 完整的键盘导航。
- 支持自定义占位符。
- 支持从右到左方向。
安装
从命令行安装组件。
$ npm add radix-vue
解剖学
导入所有部分并将它们拼凑在一起。
<script setup lang="ts">
import {
ComboboxAnchor,
ComboboxArrow,
ComboboxCancel,
ComboboxContent,
ComboboxEmpty,
ComboboxGroup,
ComboboxInput,
ComboboxItem,
ComboboxItemIndicator,
ComboboxLabel,
ComboboxPortal,
ComboboxRoot,
ComboboxSeparator,
ComboboxTrigger,
ComboboxViewport,
} from 'radix-vue'
</script>
<template>
<ComboboxRoot>
<ComboboxAnchor>
<ComboboxInput />
<ComboboxTrigger />
<ComboboxCancel />
</ComboboxAnchor>
<ComboboxPortal>
<ComboboxContent>
<ComboboxViewport>
<ComboboxEmpty />
<ComboboxItem>
<ComboboxItemIndicator />
</ComboboxItem>
<ComboboxGroup>
<ComboboxLabel />
<ComboboxItem>
<ComboboxItemIndicator />
</ComboboxItem>
</ComboboxGroup>
<ComboboxSeparator />
</ComboboxViewport>
<ComboboxArrow />
</ComboboxContent>
</ComboboxPortal>
</ComboboxRoot>
</template>
API 参考
根
包含组合框的所有部分
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 | |
defaultOpen | 布尔值 组合框在最初渲染时的打开状态。 | |
defaultValue | AcceptableValue | AcceptableValue[] 组合框在最初渲染时的值。当您不需要控制组合框的状态时使用 | |
dir | 'ltr' | 'rtl' 组合框适用的阅读方向。 | |
disabled | 布尔值 当 | |
displayValue | ((val: AcceptableValue) => string) 所选项目的输入显示值。不适用于 | |
filterFunction | ((val: string[] | number[] | false[] | true[] | Record<string, any>[], term: string) => string[] | number[] | false[] | true[] | Record<string, any>[]) 用于过滤 | |
modelValue | AcceptableValue | AcceptableValue[] 组合框的受控值。可以使用 | |
multiple | 布尔值 是否可以选择多个选项。 | |
name | 字符串 组合框的名称。作为名称/值对的一部分,与拥有它的表单一起提交。 | |
open | 布尔值 组合框的受控打开状态。可以使用 | |
resetSearchTermOnBlur | 真的 | 布尔值 组合框输入失焦时是否重置 searchTerm |
searchTerm | 字符串 组合框的受控搜索词。可以使用 v-model:searchTerm 绑定。 | |
selectedValue | AcceptableValue 组合框当前突出显示的值。可以使用 |
发射 | 有效载荷 |
---|---|
update:modelValue | [value: AcceptableValue] 值更改时调用的事件处理程序。 |
update:open | [value: 布尔值] 组合框的打开状态更改时调用的事件处理程序。 |
update:searchTerm | [value: 字符串] 组合框的 searchTerm 更改时调用的事件处理程序。 |
update:selectedValue | [value: AcceptableValue] 组合框的突出显示值更改时调用的事件处理程序 |
插槽 (默认) | 有效载荷 |
---|---|
open | 布尔值 当前打开状态 |
modelValue | AcceptableValue | AcceptableValue[] 当前活动值 |
锚点
如果将ComboboxContent
的 position 设置为popper
,则用作锚点。
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 |
输入
用于搜索组合框项目的输入组件。
道具 | 默认 | 类型 |
---|---|---|
as | '输入' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 | |
autoFocus | 布尔值 在挂载时将焦点设置到元素上。 | |
disabled | 布尔值 当 | |
type | '文本' | 字符串 本机输入类型 |
触发器
用于切换组合框内容的按钮。
道具 | 默认 | 类型 |
---|---|---|
as | '按钮' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 | |
disabled | 布尔值 当 |
数据属性 | 价值 |
---|---|
[data-state] | "打开" | "关闭" |
[data-disabled] | 禁用时出现 |
取消
用于清除搜索词的按钮。
道具 | 默认 | 类型 |
---|---|---|
as | '按钮' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 |
空
当没有项目匹配查询时显示。
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 |
传送门
使用时,会将内容部分传送到body
中。
您需要将ComboboxContent
的position
设置为popper
,以确保位置的自动计算类似于Popover
或DropdownMenu
。
道具 | 默认 | 类型 |
---|---|---|
disabled | 布尔值 禁用传送门并内联渲染组件 | |
forceMount | 布尔值 用于在需要更多控制时强制挂载。当使用 Vue 动画库控制动画时很有用。 | |
to | 字符串 | HTMLElement Vue 原生传送门组件属性 |
内容
组合框打开时弹出的组件。
道具 | 默认 | 类型 |
---|---|---|
对齐 | '开始' | '中心' | '结束' 相对于触发器的首选对齐方式。在发生冲突时可能会更改。 | |
alignOffset | 号码 与 | |
arrowPadding | 号码 箭头与内容边缘之间的填充。如果您的内容具有边框半径,这将防止它溢出角。 | |
as | 'div' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 | |
avoidCollisions | 布尔值 当 | |
bodyLock | 布尔值 文档.body 将被锁定,并且滚动将被禁用。 | |
collisionBoundary | 元素 | (元素 | 空)[] | 空 用作碰撞边界的元素。默认情况下,这是视窗,但您可以提供要包含在此检查中的其他元素。 | |
collisionPadding | 数字 | 部分<记录<'顶部' | '右侧' | '底部' | '左侧', 数字>> 从边界边缘开始,发生碰撞检测的像素距离。接受一个数字(所有侧面的相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。 | |
disableOutsidePointerEvents | 布尔值 当 | |
可关闭 | 布尔值 允许组件成为可关闭层。 | |
forceMount | 布尔值 用于在需要更多控制时强制挂载。当使用 Vue 动画库控制动画时很有用。 | |
hideWhenDetached | 布尔值 当触发器完全被遮挡时是否隐藏内容。 | |
位置 | '内联' | 'popper' 要使用的定位模式, | |
prioritizePosition | 布尔值 强制内容在视窗内定位。 可能会与参考元素重叠,这可能不是想要的。 | |
侧 | '顶部' | '右侧' | '底部' | '左侧' 打开时渲染的触发器首选侧。当发生冲突并启用 avoidCollisions 时将被反转。 | |
sideOffset | 号码 与触发器之间的像素距离。 | |
粘性 | '部分' | '总是' 对齐轴上的粘性行为。 | |
updatePositionStrategy | '总是' | '优化' 在每个动画帧更新浮动元素位置的策略。 |
发射 | 有效载荷 |
---|---|
escapeKeyDown | [事件: KeyboardEvent] 按下 Escape 键时调用的事件处理程序。可以阻止。 |
focusOutside | [事件: FocusOutsideEvent] 焦点移出 |
interactOutside | [事件: PointerDownOutsideEvent | FocusOutsideEvent] 在 |
pointerDownOutside | [事件: PointerDownOutsideEvent] 当 |
数据属性 | 价值 |
---|---|
[data-state] | "打开" | "关闭" |
[data-side] | "left" | "right" | "bottom" | "top" |
[data-align] | "start" | "end" | "center" |
CSS 变量 | 描述 |
---|---|
--radix-combobox-content-transform-origin | 从内容和箭头位置/偏移量计算出的 transform-origin 。仅在 position="popper" 时存在。 |
--radix-combobox-content-available-width | 触发器和边界边缘之间的剩余宽度。仅在 position="popper" 时存在。 |
--radix-combobox-content-available-height | 触发器和边界边缘之间的剩余高度。仅在 position="popper" 时存在。 |
--radix-combobox-trigger-width | 触发器的宽度。仅在 position="popper" 时存在。 |
--radix-combobox-trigger-height | 触发器的高度。仅在 position="popper" 时存在。 |
视窗
包含所有项目的滚动视窗。
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 | |
nonce | 字符串 将 |
项目
包含下拉框项目的组件。
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 | |
disabled | 布尔值 当为 | |
value* | AcceptableValue 使用 |
发射 | 有效载荷 |
---|---|
select | [事件: SelectEvent<AcceptableValue>] 选择项目时调用的事件处理程序。 |
数据属性 | 价值 |
---|---|
[data-state] | "checked" | "unchecked" |
[data-highlighted] | 高亮显示时存在 |
[data-disabled] | 禁用时出现 |
项目指示器
在项目被选中时渲染。你可以直接为这个元素设置样式,或者你可以将它用作包装器,将一个图标放在里面,或者两者兼而有之。
道具 | 默认 | 类型 |
---|---|---|
as | 'span' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 |
组
用于对多个项目进行分组。与 ComboboxLabel
结合使用,以确保通过自动标记实现良好的可访问性。
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 |
标签
用于渲染组的标签。它不能使用箭头键获得焦点。
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 | |
for | 字符串 |
分隔符
用于在下拉框中视觉上分隔项目
道具 | 默认 | 类型 |
---|---|---|
as | 'div' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 |
箭头
一个可选的箭头元素,用于与内容一起渲染。这可以用来帮助视觉上将触发器与 ComboboxContent
连接起来。必须在 ComboboxContent
内部渲染。仅在 position
设置为 popper
时可用。
道具 | 默认 | 类型 |
---|---|---|
as | 'svg' | AsTag | 组件 此组件应渲染的元素或组件。可以通过 |
asChild | 布尔值 将默认渲染的元素更改为作为子元素传递的元素,合并它们的属性和行为。 阅读我们的组合指南以了解更多详细信息。 | |
高度 | 5 | 号码 箭头的像素高度。 |
宽度 | 10 | 号码 箭头的像素宽度。 |
示例
将对象绑定为值
与只能提供字符串作为值的原生 HTML 表单控件不同,radix-vue
也支持绑定复杂对象。
确保设置 displayValue
属性,以便在项目选择时设置输入值。
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxContent, ComboboxInput, ComboboxItem, ComboboxPortal, ComboboxRoot } from 'radix-vue'
const people = [
{ id: 1, name: 'Durward Reynolds' },
{ id: 2, name: 'Kenton Towne' },
{ id: 3, name: 'Therese Wunsch' },
{ id: 4, name: 'Benedict Kessler' },
{ id: 5, name: 'Katelyn Rohan' },
]
const selectedPeople = ref(people[0])
</script>
<template>
<ComboboxRoot
v-model="selectedPeople"
:display-value="(v) => v.name"
>
<ComboboxInput />
<ComboboxPortal>
<ComboboxContent>
<ComboboxItem
v-for="person in people"
:key="person.id"
:value="person"
:disabled="person.unavailable"
>
{{ person.name }}
</ComboboxItem>
</ComboboxContent>
</ComboboxPortal>
</ComboboxRoot>
</template>
选择多个值
Combobox
组件允许你选择多个值。你可以通过提供一个值数组而不是单个值来启用此功能。
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxRoot } from 'radix-vue'
const people = [
{ id: 1, name: 'Durward Reynolds' },
{ id: 2, name: 'Kenton Towne' },
{ id: 3, name: 'Therese Wunsch' },
{ id: 4, name: 'Benedict Kessler' },
{ id: 5, name: 'Katelyn Rohan' },
]
const selectedPeople = ref([people[0], people[1]])
</script>
<template>
<ComboboxRoot
v-model="selectedPeople"
multiple
>
...
</ComboboxRoot>
</template>
自定义过滤
在内部,ComboboxRoot
将应用默认的 过滤器函数 来过滤相关的 ComboboxItem
(仅在 modelValue
类型为 string
时应用)。
但是,可以使用两种不同的方法来替换此行为。
1. 提供 filter-function
属性。
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxContent, ComboboxInput, ComboboxItem, ComboboxPortal, ComboboxRoot } from 'radix-vue'
const people = [
{ id: 1, name: 'Durward Reynolds' },
{ id: 2, name: 'Kenton Towne' },
{ id: 3, name: 'Therese Wunsch' },
{ id: 4, name: 'Benedict Kessler' },
{ id: 5, name: 'Katelyn Rohan' },
]
const selectedPeople = ref(people[0])
function filterFunction(list: typeof people[number], searchTerm: string) {
return list.filter((person) => {
return person.name.toLowerCase().includes(searchTerm.toLowerCase())
})
}
</script>
<template>
<ComboboxRoot
v-model="selectedPeople"
:filter-function="filterFunction"
>
<ComboboxInput />
<ComboboxPortal>
<ComboboxContent>
<ComboboxItem
v-for="person in people"
:key="person.id"
:value="person"
:disabled="person.unavailable"
>
{{ person.name }}
</ComboboxItem>
</ComboboxContent>
</ComboboxPortal>
</ComboboxRoot>
</template>
2. 过滤后的 v-for
选项
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxContent, ComboboxInput, ComboboxItem, ComboboxPortal, ComboboxRoot } from 'radix-vue'
const people = [
{ id: 1, name: 'Durward Reynolds' },
{ id: 2, name: 'Kenton Towne' },
{ id: 3, name: 'Therese Wunsch' },
{ id: 4, name: 'Benedict Kessler' },
{ id: 5, name: 'Katelyn Rohan' },
]
const selectedPeople = ref(people[0])
const searchTerm = ref('')
const filteredPeople = computed(() =>
searchTerm.value === ''
? people
: people.filter((person) => {
return person.name.toLowerCase().includes(searchTerm.value.toLowerCase())
})
)
</script>
<template>
<ComboboxRoot
v-model="selectedPeople"
v-model:searchTerm="searchTerm"
>
<ComboboxInput />
<ComboboxPortal>
<ComboboxContent>
<ComboboxItem
v-for="person in filteredPeople"
:key="person.id"
:value="person"
:disabled="person.unavailable"
>
{{ person.name }}
</ComboboxItem>
</ComboboxContent>
</ComboboxPortal>
</ComboboxRoot>
</template>
自定义标签
默认情况下,Combobox
将使用输入内容作为屏幕阅读器的标签。如果你想要更详细地控制向辅助技术宣布的内容,请使用 Label 组件。
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxInput, ComboboxRoot, Label } from 'radix-vue'
</script>
<template>
<ComboboxRoot v-model="selectedPeople">
<Label for="person">Person: </Label>
<ComboboxInput
id="person"
placeholder="Select a person"
/>
...
</ComboboxRoot>
</template>
包含禁用项目
你可以使用 data-disabled
属性为禁用项目添加特殊样式。
<script setup lang="ts">
import { ref } from 'vue'
import {
ComboboxContent,
ComboboxInput,
ComboboxItem,
ComboboxPortal,
ComboboxRoot,
} from 'radix-vue'
</script>
<template>
<ComboboxRoot>
<ComboboxInput />
<ComboboxPortal>
<ComboboxContent>
<ComboboxItem
class="ComboboxItem"
disabled
>
...
</ComboboxItem>
</ComboboxContent>
</ComboboxPortal>
</ComboboxRoot>
</template>
/* styles.css */
.ComboboxItem[data-disabled] {
color: "gainsboro";
}
包含分隔符
使用 Separator
部分在项目之间添加分隔符。
<script setup lang="ts">
import { ref } from 'vue'
import {
ComboboxContent,
ComboboxInput,
ComboboxItem,
ComboboxPortal,
ComboboxRoot,
ComboboxSeparator
} from 'radix-vue'
</script>
<template>
<ComboboxRoot>
<ComboboxInput />
<ComboboxPortal>
<ComboboxContent>
<ComboboxItem>…</ComboboxItem>
<ComboboxItem>…</ComboboxItem>
<ComboboxItem>…</ComboboxItem>
<ComboboxSeparator />
<ComboboxItem>…</ComboboxItem>
<ComboboxItem>…</ComboboxItem>
<ComboboxItem>…</ComboboxItem>
</ComboboxContent>
</ComboboxPortal>
</ComboboxRoot>
</template>
包含分组项目
使用 Group
和 Label
部分将项目分组在一个部分中。
<script setup lang="ts">
import { ref } from 'vue'
import {
ComboboxContent,
ComboboxGroup,
ComboboxInput,
ComboboxItem,
ComboboxLabel,
ComboboxPortal,
ComboboxRoot
} from 'radix-vue'
</script>
<template>
<ComboboxRoot>
<ComboboxInput />
<ComboboxPortal>
<ComboboxContent>
<ComboboxGroup>
<ComboboxLabel>Label</ComboboxLabel>
<ComboboxItem>…</ComboboxItem>
<ComboboxItem>…</ComboboxItem>
<ComboboxItem>…</ComboboxItem>
</ComboboxGroup>
</ComboboxContent>
</ComboboxPortal>
</ComboboxRoot>
</template>
包含复杂项目
你可以在项目中使用自定义内容。
<script setup lang="ts">
import { ref } from 'vue'
import {
ComboboxContent,
ComboboxGroup,
ComboboxInput,
ComboboxItem,
ComboboxItemIndicator,
ComboboxLabel,
ComboboxPortal,
ComboboxRoot
} from 'radix-vue'
</script>
<template>
<ComboboxRoot>
<ComboboxInput />
<ComboboxPortal>
<ComboboxContent>
<ComboboxItem>
<img src="…">
Adolfo Hess
<ComboboxItemIndicator />
</ComboboxItem>
…
</ComboboxContent>
</ComboboxPortal>
</ComboboxRoot>
</template>
阻止选择行为
默认情况下,选择 ComboboxItem
将关闭内容,并使用提供的值更新 modelValue
。你可以通过阻止默认的 @select.prevent
来阻止此行为。
<script setup lang="ts">
import { ref } from 'vue'
import { ComboboxContent, ComboboxGroup, ComboboxInput, ComboboxItem, ComboboxItemIndicator, ComboboxLabel, ComboboxPortal, ComboboxRoot } from 'radix-vue'
</script>
<template>
<ComboboxRoot>
<ComboboxInput />
<ComboboxPortal>
<ComboboxContent>
<ComboboxItem @select.prevent>
Item A
</ComboboxItem>
…
</ComboboxContent>
</ComboboxPortal>
</ComboboxRoot>
</template>
可访问性
有关更多信息,请参阅 W3C 下拉框自动完成列表 示例。
键盘交互
键 | 描述 |
---|---|
Enter | 当 ComboboxItem 获得焦点时,选择获得焦点的项目。 |
ArrowDown | 当 ComboboxInput 获得焦点时,打开下拉框内容。当项目获得焦点时,将焦点移至下一个项目。 |
ArrowUp | 当 ComboboxInput 获得焦点时,打开下拉框内容。当项目获得焦点时,将焦点移至上一个项目。 |
Esc | 关闭下拉框,并恢复 ComboboxInput 字段中的所选项目。 |
自定义 API
通过将基本部分抽象到自己的组件中来创建自己的 API。
命令菜单
下拉框可用于构建自己的命令菜单。
用法
<script setup lang="ts">
import { Command, CommandItem } from './your-command'
</script>
<template>
<Command>
<CommandItem value="1">
Item 1
</CommandItem>
<CommandItem value="2">
Item 2
</CommandItem>
<CommandItem value="3">
Item 3
</CommandItem>
</Command>
</template>
实现
// your-command.ts
export { default as Command } from 'Command.vue'
export { default as CommandItem } from 'CommandItem.vue'
<!-- Command.vue -->
<script setup lang="ts">
import { CheckIcon, ChevronDownIcon, ChevronUpIcon, } from '@radix-icons/vue'
import { ComboboxContent, ComboboxEmpty, ComboboxInput, ComboboxPortal, ComboboxRoot, useForwardPropsEmits } from 'radix-vue'
import type { ComboboxRootEmits, ComboboxRootProps } from 'radix-vue'
const props = defineProps<ComboboxRootProps>()
const emits = defineEmits<ComboboxRootEmits>()
const forward = useForwardPropsEmits(props, emits)
</script>
<template>
<ComboboxRoot
v-bind="forward"
:open="true"
model-value=""
>
<ComboboxInput placeholder="Type a command or search..." />
<ComboboxPortal>
<ComboboxContent>
<ComboboxEmpty />
<ComboboxViewport>
<slot />
</ComboboxViewport>
</ComboboxContent>
</ComboboxPortal>
</ComboboxRoot>
</template>
<!-- ComboboxItem.vue -->
<script setup lang="ts">
import { CheckIcon } from '@radix-icons/vue'
import { ComboboxItem, type ComboboxItemProps } from 'radix-vue'
const props = defineProps<ComboboxItemProps>()
</script>
<template>
<ComboboxItem
v-bind="props"
@select.prevent
>
<slot />
</ComboboxItem>
</template>