Appearance
Select 选择器
从弹出列表中选择一个或多个值。
命令行安装
bash
npx @loongship-kit/ui add select组件结构
| 角色 | 组件 | 职责 | 使用条件 |
|---|---|---|---|
| 根组件 | Select | 管理选中值和展开状态 | 必需 |
| 触发区域 | SelectTrigger、SelectValue | 打开选项列表并展示当前值 | 常规用法需要 |
| 内容容器 | SelectContent | 承载并定位选项列表 | 必需 |
| 选项结构 | SelectGroup、SelectLabel、SelectItem | 组织分组、标签和可选项 | SelectItem 必需 |
| 辅助组件 | SelectSeparator、SelectScrollUpButton、SelectScrollDownButton | 分隔选项并提供滚动控制 | 按需 |
基础用法
查看代码
vue
<script setup lang="ts">
import { ref } from 'vue'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue
} from '@/components/loongship/select'
const port = ref<string>()
</script>
<template>
<Select v-model="port">
<SelectTrigger aria-label="Port">
<SelectValue placeholder="Select a port" />
</SelectTrigger>
<SelectContent>
<SelectItem value="cnsgh">Shanghai</SelectItem>
<SelectItem value="sgsin">Singapore</SelectItem>
<SelectItem value="jpyok">Yokohama</SelectItem>
</SelectContent>
</Select>
</template>分组和禁用项
Selected: cnsgh
查看代码
vue
<template>
<Select v-model="port">
<SelectTrigger><SelectValue /></SelectTrigger>
<SelectContent>
<SelectGroup>
<SelectLabel>Asia</SelectLabel>
<SelectItem value="cnsgh">Shanghai</SelectItem>
<SelectItem value="sgsin">Singapore</SelectItem>
</SelectGroup>
<SelectSeparator />
<SelectGroup>
<SelectLabel>Europe</SelectLabel>
<SelectItem value="nlrtm">Rotterdam</SelectItem>
<SelectItem value="deham" disabled>Hamburg (unavailable)</SelectItem>
</SelectGroup>
</SelectContent>
</Select>
</template>多选
多选值与展示
设置 multiple 后,v-model 使用数组。触发器默认用逗号连接已选项文本。
Selected: underway
查看代码
vue
<script setup lang="ts">
import { ref } from 'vue'
import { Button } from '@/components/loongship/button'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue
} from '@/components/loongship/select'
const statuses = ref<string[]>(['underway'])
</script>
<template>
<div class="vp-demo-showcase-column">
<div class="vp-demo-control">
<Select v-model="statuses" multiple>
<SelectTrigger aria-label="Vessel statuses">
<SelectValue placeholder="Select statuses" />
</SelectTrigger>
<SelectContent>
<SelectItem value="underway">Underway</SelectItem>
<SelectItem value="moored">Moored</SelectItem>
<SelectItem value="anchor">At anchor</SelectItem>
<SelectItem value="unknown" disabled>Unknown (unavailable)</SelectItem>
</SelectContent>
</Select>
</div>
<span>Selected: {{ statuses.join(', ') || 'None' }}</span>
<Button size="sm" variant="outline" @click="statuses = []">Clear</Button>
</div>
</template>禁用
查看代码
vue
<template>
<Select disabled default-value="cnsgh">
<SelectTrigger aria-label="Disabled port">
<SelectValue />
</SelectTrigger>
<SelectContent>
<SelectItem value="cnsgh">Shanghai</SelectItem>
</SelectContent>
</Select>
</template>受控展开
受控状态行为
使用 v-model:open 读取或控制展开状态。默认不会锁定页面滚动。
Open: false
查看代码
vue
<script setup lang="ts">
import { ref } from 'vue'
import { Button } from '@/components/loongship/button'
import {
Select,
SelectContent,
SelectItem,
SelectTrigger,
SelectValue
} from '@/components/loongship/select'
const open = ref(false)
</script>
<template>
<Button size="sm" variant="outline" @click="open = true">Open select</Button>
<Select v-model:open="open">
<SelectTrigger aria-label="Controlled select">
<SelectValue placeholder="Select a status" />
</SelectTrigger>
<SelectContent>
<SelectItem value="underway">Underway</SelectItem>
<SelectItem value="moored">Moored</SelectItem>
<SelectItem value="anchor">At anchor</SelectItem>
</SelectContent>
</Select>
<span>Open: {{ open }}</span>
</template>API
Select(主组件)
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
v-model | AcceptableValue | AcceptableValue[] | - | 当前选中值 |
defaultValue | AcceptableValue | AcceptableValue[] | - | 非受控模式的初始值 |
v-model:open | boolean | - | 展开状态 |
defaultOpen | boolean | false | 非受控模式的初始展开状态 |
multiple | boolean | false | 是否允许多选;开启后 modelValue 为数组 |
nullableValue | string | - | 空值时原生隐藏选项的值 |
by | string | ((a, b) => boolean) | - | 对象值的比较字段或比较函数 |
dir | 'ltr' | 'rtl' | 'ltr' | 阅读方向 |
autocomplete | string | - | 表单自动完成提示 |
disabled | boolean | false | 是否禁用 |
name | string | - | 表单字段名 |
required | boolean | false | 是否必填 |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
update:modelValue | value: AcceptableValue | AcceptableValue[] | 选中值改变时触发 |
update:open | open: boolean | 展开状态改变时触发 |
插槽
| 插槽 | 参数 | 说明 |
|---|---|---|
default | — | 放置 SelectTrigger 和 SelectContent |
子组件
SelectTrigger — 选择器触发区域
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
disabled | boolean | false | 单独禁用触发器 |
reference | Element | VirtualElement | 当前元素 | 自定义浮层定位锚点 |
as | string | Component | 'button' | 渲染元素 |
asChild | boolean | false | 合并到唯一子元素 |
class | ClassValue | - | 自定义类名 |
插槽
| 插槽 | 参数 | 说明 |
|---|---|---|
default | — | 放置 SelectValue |
SelectValue — 当前选中值
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
placeholder | string | - | 未选择时显示的占位文本 |
as | string | Component | 'span' | 渲染元素 |
asChild | boolean | false | 合并到唯一子元素 |
class | ClassValue | - | 自定义类名 |
插槽
| 插槽 | 参数 | 说明 |
|---|---|---|
default | { selectedLabel: string[], modelValue: AcceptableValue | AcceptableValue[] | undefined } | 自定义选中值内容 |
SelectContent — 选项浮层容器
属性
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
position | 'item-aligned' | 'popper' | 'popper' | 浮层定位模式 |
bodyLock | boolean | false | 展开时是否锁定页面滚动;设为 true 时页面滚动条会隐藏 |
forceMount | boolean | false | 关闭时仍保留内容节点 |
disableOutsidePointerEvents | boolean | false | 是否阻止浮层外的指针事件 |
side | 'top' | 'right' | 'bottom' | 'left' | 'bottom' | 首选展开方向 |
sideOffset | number | 0 | 与触发器的距离 |
sideFlip | boolean | true | 空间不足时是否翻转方向 |
align | 'start' | 'center' | 'end' | 'center' | 与触发器的对齐方式 |
alignOffset | number | 0 | 对齐偏移量 |
alignFlip | boolean | true | 碰撞时是否翻转对齐方式 |
avoidCollisions | boolean | true | 是否避免超出边界 |
collisionBoundary | Element | null | Array<Element | null> | [] | 碰撞检测边界 |
collisionPadding | number | Partial<Record<Side, number>> | 0 | 碰撞边界内边距 |
arrowPadding | number | 0 | 箭头与内容边缘的间距 |
hideShiftedArrow | boolean | true | 箭头无法居中时是否隐藏 |
sticky | 'partial' | 'always' | 'partial' | 对齐轴上的粘附策略 |
hideWhenDetached | boolean | false | 锚点不可见时是否隐藏 |
positionStrategy | 'absolute' | 'fixed' | 'fixed' | CSS 定位策略 |
updatePositionStrategy | 'optimized' | 'always' | 'optimized' | 浮层位置更新策略 |
disableUpdateOnLayoutShift | boolean | false | 布局变化时停止更新位置 |
prioritizePosition | boolean | false | 优先保证浮层位于视口内 |
reference | Element | VirtualElement | 触发器 | 自定义定位锚点 |
dir | 'ltr' | 'rtl' | 'ltr' | 阅读方向 |
memoDependencies | unknown[] | - | 触发内容子树更新的依赖 |
as | string | Component | 'div' | 渲染元素 |
asChild | boolean | false | 合并到唯一子元素 |
class | ClassValue | - | 自定义类名 |
事件
| 事件 | 参数 | 说明 |
|---|---|---|
escapeKeyDown | KeyboardEvent | 按下 Escape 时触发,可阻止默认行为 |
pointerDownOutside | PointerDownOutsideEvent | 在浮层外按下指针时触发,可阻止默认行为 |
closeAutoFocus | Event | 关闭后恢复焦点前触发,可阻止默认行为 |
插槽
| 插槽 | 参数 | 说明 |
|---|---|---|
default | — | 放置分组、选项和分割线 |
SelectGroup / SelectLabel / SelectItem — 分组、标签与选项
属性
| 组件 | 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
SelectGroup | as | string | Component | 'div' | 渲染元素 |
SelectGroup | asChild | boolean | false | 合并到唯一子元素 |
SelectGroup | class | ClassValue | - | 自定义类名 |
SelectLabel | for | string | - | 关联分组的元素 id |
SelectLabel | as | string | Component | 'div' | 渲染元素 |
SelectLabel | asChild | boolean | false | 合并到唯一子元素 |
SelectLabel | class | ClassValue | - | 自定义类名 |
SelectItem | value | AcceptableValue | - | 选项值,必填 |
SelectItem | disabled | boolean | false | 是否禁用 |
SelectItem | textValue | string | 文本内容 | 键盘字符检索使用的文本 |
SelectItem | as | string | Component | 'div' | 渲染元素 |
SelectItem | asChild | boolean | false | 合并到唯一子元素 |
SelectItem | class | ClassValue | - | 自定义类名 |
事件
| 组件 | 事件 | 参数 | 说明 |
|---|---|---|---|
SelectItem | select | SelectEvent | 选择前触发;调用 event.preventDefault() 可阻止选择 |
插槽
| 组件 | 插槽 | 参数 | 说明 |
|---|---|---|---|
SelectGroup | default | — | 分组内容 |
SelectLabel | default | — | 分组标签 |
SelectItem | default | — | 选项内容 |
SelectSeparator / / — 分隔与滚动辅助
属性
| 组件 | 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
SelectSeparator | as | string | Component | 'div' | 渲染元素 |
SelectSeparator | asChild | boolean | false | 合并到唯一子元素 |
SelectSeparator | class | ClassValue | - | 自定义类名 |
SelectScrollUpButton | as | string | Component | 'div' | 渲染元素 |
SelectScrollUpButton | asChild | boolean | false | 合并到唯一子元素 |
SelectScrollUpButton | class | ClassValue | - | 自定义类名 |
SelectScrollDownButton | as | string | Component | 'div' | 渲染元素 |
SelectScrollDownButton | asChild | boolean | false | 合并到唯一子元素 |
SelectScrollDownButton | class | ClassValue | - | 自定义类名 |