Skip to content

选择器 Select

下拉选择器

何时使用

  • 弹出一个下拉菜单给用户选择操作,用于代替原生的选择器,或者需要一个更优雅的多选器时
  • 当选项少时(少于 5 项),建议直接将选项平铺,使用 Radio 是更好的选择

基本使用

Show Code
vue
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const options = ref<SelectOption[]>([
  {
    label: '北京市',
    value: 1
  },
  {
    label: '上海市',
    value: 2
  },
  {
    label: '纽约市',
    value: 3
  },
  {
    label: '旧金山',
    value: 4
  },
  {
    label: '布宜诺斯艾利斯',
    value: 5
  },
  {
    label: '伊斯坦布尔',
    value: 6
  },
  {
    label: '拜占庭',
    value: 7
  },
  {
    label: '君士坦丁堡',
    value: 8
  }
])
const selectedValue = ref<SelectProps['modelValue']>(5)
watchEffect(() => {
  console.log('selectedValue', selectedValue.value)
})
function onChange(value: string | number, label: string, index: number) {
  console.log('value', value)
  console.log('label', label)
  console.log('index', index)
}
function onOpenChange(open: boolean) {
  console.log('openChange', open)
}
</script>
<template>
  <Select :options="options" v-model="selectedValue" @change="onChange" @openChange="onOpenChange" />
</template>

禁用

Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const options = ref<SelectOption[]>([
  {
    label: '北京市',
    value: 1
  },
  {
    label: '上海市',
    value: 2
  },
  {
    label: '纽约市',
    value: 3
  },
  {
    label: '旧金山',
    value: 4
  },
  {
    label: '布宜诺斯艾利斯',
    value: 5
  },
  {
    label: '伊斯坦布尔',
    value: 6
  },
  {
    label: '拜占庭',
    value: 7
  },
  {
    label: '君士坦丁堡',
    value: 8
  }
])
const selectedValue = ref<SelectProps['modelValue']>(5)
</script>
<template>
  <Select :options="options" v-model="selectedValue" disabled />
</template>

禁用选项

Show Code
vue
<script setup lang="ts">
import { ref } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const optionsDisabled = ref<SelectOption[]>([
  {
    label: '北京市',
    value: 1
  },
  {
    label: '上海市',
    value: 2,
    disabled: true
  },
  {
    label: '纽约市',
    value: 3
  },
  {
    label: '旧金山',
    value: 4
  },
  {
    label: '布宜诺斯艾利斯',
    value: 5
  },
  {
    label: '伊斯坦布尔',
    value: 6
  },
  {
    label: '拜占庭',
    value: 7
  },
  {
    label: '君士坦丁堡',
    value: 8
  }
])
const selectedValue = ref<SelectProps['modelValue']>(5)
</script>
<template>
  <Select :options="optionsDisabled" v-model="selectedValue" />
</template>

自定义节点字段名

Show Code
vue
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const optionsCustom = ref<SelectOption[]>([
  {
    name: '北京市',
    id: 1
  },
  {
    name: '上海市',
    id: 2
  },
  {
    name: '纽约市',
    id: 3
  },
  {
    name: '旧金山',
    id: 4
  },
  {
    name: '布宜诺斯艾利斯',
    id: 5
  },
  {
    name: '伊斯坦布尔',
    id: 6
  },
  {
    name: '拜占庭',
    id: 7
  },
  {
    name: '君士坦丁堡',
    id: 8
  }
])
const selectedValue = ref<SelectProps['modelValue']>(5)
watchEffect(() => {
  console.log('selectedValue', selectedValue.value)
})
</script>
<template>
  <Select :options="optionsCustom" label="name" value="id" v-model="selectedValue" />
</template>

自定义样式

Show Code
vue
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const options = ref<SelectOption[]>([
  {
    label: '北京市',
    value: 1
  },
  {
    label: '上海市',
    value: 2
  },
  {
    label: '纽约市',
    value: 3
  },
  {
    label: '旧金山',
    value: 4
  },
  {
    label: '布宜诺斯艾利斯',
    value: 5
  },
  {
    label: '伊斯坦布尔',
    value: 6
  },
  {
    label: '拜占庭',
    value: 7
  },
  {
    label: '君士坦丁堡',
    value: 8
  }
])
const selectedValue = ref<SelectProps['modelValue']>(5)
watchEffect(() => {
  console.log('selectedValue', selectedValue.value)
})
</script>
<template>
  <Select :width="150" :height="36" :options="options" v-model="selectedValue" />
</template>

三种尺寸

small
middle
large
Show Code
vue
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const options = ref<SelectOption[]>([
  {
    label: '北京市',
    value: 1
  },
  {
    label: '上海市',
    value: 2
  },
  {
    label: '纽约市',
    value: 3
  },
  {
    label: '旧金山',
    value: 4
  },
  {
    label: '布宜诺斯艾利斯',
    value: 5
  },
  {
    label: '伊斯坦布尔',
    value: 6
  },
  {
    label: '拜占庭',
    value: 7
  },
  {
    label: '君士坦丁堡',
    value: 8
  }
])
const sizeOptions = [
  {
    label: 'small',
    value: 'small'
  },
  {
    label: 'middle',
    value: 'middle'
  },
  {
    label: 'large',
    value: 'large'
  }
]
const size = ref('large')
const selectedValue = ref<SelectProps['modelValue']>(5)
watchEffect(() => {
  console.log('selectedValue', selectedValue.value)
})
</script>
<template>
  <Space vertical>
    <Radio :options="sizeOptions" v-model:value="size" button button-style="solid" />
    <Select :options="options" v-model="selectedValue" :size="size" />
    <Select :options="options" search allowClear v-model="selectedValue" :size="size" />
  </Space>
</template>

支持清除

Show Code
vue
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const options = ref<SelectOption[]>([
  {
    label: '北京市',
    value: 1
  },
  {
    label: '上海市',
    value: 2
  },
  {
    label: '纽约市',
    value: 3
  },
  {
    label: '旧金山',
    value: 4
  },
  {
    label: '布宜诺斯艾利斯',
    value: 5
  },
  {
    label: '伊斯坦布尔',
    value: 6
  },
  {
    label: '拜占庭',
    value: 7
  },
  {
    label: '君士坦丁堡',
    value: 8
  }
])
const selectedValue = ref<SelectProps['modelValue']>(5)
watchEffect(() => {
  console.log('selectedValue', selectedValue.value)
})
</script>
<template>
  <Select :options="options" allow-clear v-model="selectedValue" />
</template>

支持搜索

Show Code
vue
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const options = ref<SelectOption[]>([
  {
    label: '北京市',
    value: 1
  },
  {
    label: '上海市',
    value: 2
  },
  {
    label: '纽约市',
    value: 3
  },
  {
    label: '旧金山',
    value: 4
  },
  {
    label: '布宜诺斯艾利斯',
    value: 5
  },
  {
    label: '伊斯坦布尔',
    value: 6
  },
  {
    label: '拜占庭',
    value: 7
  },
  {
    label: '君士坦丁堡',
    value: 8
  }
])
const selectedValue = ref<SelectProps['modelValue']>(5)
watchEffect(() => {
  console.log('selectedValue', selectedValue.value)
})
</script>
<template>
  <Select :options="options" allow-clear search v-model="selectedValue" />
</template>

搜索过滤函数

Show Code
vue
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const options = ref<SelectOption[]>([
  {
    label: '北京市',
    value: 1
  },
  {
    label: '上海市',
    value: 2
  },
  {
    label: '纽约市',
    value: 3
  },
  {
    label: '旧金山',
    value: 4
  },
  {
    label: '布宜诺斯艾利斯',
    value: 5
  },
  {
    label: '伊斯坦布尔',
    value: 6
  },
  {
    label: '拜占庭',
    value: 7
  },
  {
    label: '君士坦丁堡',
    value: 8
  }
])
const selectedValue = ref<SelectProps['modelValue']>(5)
watchEffect(() => {
  console.log('selectedValue', selectedValue.value)
})
// 自定义过滤函数,当选项的 value 值大于 输入项时返回 true
function filter(inputValue: string, option: any) {
  return option.value > inputValue
}
</script>
<template>
  <Select :options="options" search :filter="filter" v-model="selectedValue" />
</template>

下拉面板弹出位置

bottom
top
Show Code
vue
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const options = ref<SelectOption[]>([
  {
    label: '北京市',
    value: 1
  },
  {
    label: '上海市',
    value: 2
  },
  {
    label: '纽约市',
    value: 3
  },
  {
    label: '旧金山',
    value: 4
  },
  {
    label: '布宜诺斯艾利斯',
    value: 5
  },
  {
    label: '伊斯坦布尔',
    value: 6
  },
  {
    label: '拜占庭',
    value: 7
  },
  {
    label: '君士坦丁堡',
    value: 8
  }
])
const placementOptions = [
  {
    label: 'bottom',
    value: 'bottom'
  },
  {
    label: 'top',
    value: 'top'
  }
]
const placement = ref('bottom')
const selectedValue = ref<SelectProps['modelValue']>(5)
watchEffect(() => {
  console.log('selectedValue', selectedValue.value)
})
</script>
<template>
  <Space vertical>
    <Radio :options="placementOptions" v-model:value="placement" button button-style="solid" />
    <Select :options="options" v-model="selectedValue" :placement="placement" />
    <Select :options="options" search allow-clear v-model="selectedValue" :placement="placement" />
  </Space>
</template>

下拉面板数

Show Code
vue
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const options = ref<SelectOption[]>([
  {
    label: '北京市',
    value: 1
  },
  {
    label: '上海市',
    value: 2
  },
  {
    label: '纽约市',
    value: 3
  },
  {
    label: '旧金山',
    value: 4
  },
  {
    label: '布宜诺斯艾利斯',
    value: 5
  },
  {
    label: '伊斯坦布尔',
    value: 6
  },
  {
    label: '拜占庭',
    value: 7
  },
  {
    label: '君士坦丁堡',
    value: 8
  }
])
const selectedValue = ref<SelectProps['modelValue']>(5)
watchEffect(() => {
  console.log('selectedValue', selectedValue.value)
})
</script>
<template>
  <Select :options="options" :max-display="5" v-model="selectedValue" />
</template>

下拉面板滚动条

Show Code
vue
<script setup lang="ts">
import { ref, watchEffect } from 'vue'
import type { SelectProps, SelectOption } from 'vue-amazing-ui'
const options = ref<SelectOption[]>([
  {
    label: '北京市',
    value: 1
  },
  {
    label: '上海市',
    value: 2
  },
  {
    label: '纽约市',
    value: 3
  },
  {
    label: '旧金山',
    value: 4
  },
  {
    label: '布宜诺斯艾利斯',
    value: 5
  },
  {
    label: '伊斯坦布尔',
    value: 6
  },
  {
    label: '拜占庭',
    value: 7
  },
  {
    label: '君士坦丁堡',
    value: 8
  }
])
const selectedValue = ref<SelectProps['modelValue']>(5)
watchEffect(() => {
  console.log('selectedValue', selectedValue.value)
})
</script>
<template>
  <Select :options="options" v-model="selectedValue" :scrollbar-props="{ size: 8, delay: 2000 }" />
</template>

APIs

Select

参数说明类型默认值
options选项数据Option[][]
label选项的 label 文本字段名string'label'
value选项的 value 值字段名string'value'
placeholder默认占位文本string'请选择'
disabled是否禁用booleanfalse
width选择器宽度,单位 pxstring | number'auto'
height选择器高度,单位 pxnumberundefined
size选择器大小'small' | 'middle' | 'large''middle'
allowClear是否支持清除booleanfalse
search是否支持搜索booleanfalse
placement下拉面板弹出位置'bottom' | 'top''bottom'
flip下拉面板被浏览器窗口或最近可滚动父元素遮挡时自动调整弹出位置booleantrue
to下拉面板挂载的容器节点,可选:元素标签名 (例如 'body') 或者元素本身,false 会待在原地string | HTMLElement | false'body'
filter过滤条件函数,仅当支持搜索时生效,根据输入项进行筛选:
  • 默认为 true 时,筛选每个选项的文本字段 label 是否包含输入项,包含时返回 true,反之返回 false
  • 当其为函数 Function 时,接受 inputValue option 两个参数,当 option 符合筛选条件时,应返回 true,反之则返回 false
  • Function | truetrue
    maxDisplay下拉面板最多能展示的项数,超过后滚动显示number6
    scrollbarProps下拉面板滚动条 scrollbar 组件属性配置,参考 Scrollbar Propsobject{}
    modelValue
    v-model
    当前选中的 option 条目值number | stringundefined

    Option Type

    名称说明类型默认值
    label?选项名stringundefined
    value?选项值string | numberundefined
    disabled?是否禁用选项booleanfalse
    [propName: string]用于包含带有任意数量的其他属性anyundefined

    Events

    名称说明类型
    change选项值改变后的回调(value: string | number, label: string, index: number) => void
    openChange下拉菜单展开收起的回调(open: boolean) => void

    Released under the MIT License.